We're a community of 1077K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,076,459 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Start New Discussion Reply to this Discussion

Thread scheduling problem

I have executed the below program several times, most of the time i got the same out put but some times output is different.
sample out put is:

skylab@skylab:~/Nx/Thrds$ gcc 3.c -lpthread
skylab@skylab:~/Nx/Thrds$ ./a.out
Scheduling policy = ???
arg = 20
1arg = 20
thrd 1 schded
2arg = 10
thrd 2 schded
skylab@skylab:~/Nx/Thrds$ ./a.out
Scheduling policy = ???
arg = 20
1arg = 20
thrd 1 schded
2arg = 10
thrd 2 schded
skylab@skylab:~/Nx/Thrds$ ./a.out
Scheduling policy = ???
arg = 20
1arg = 20
thrd 1 schded
2arg = 10
thrd 2 schded
skylab@skylab:~/Nx/Thrds$ ./a.out
Scheduling policy = ???
arg = 20
1arg = 20
2arg = 20
thrd 1 schded
thrd 2 schded
skylab@skylab:~/Nx/Thrds$ ./a.out
Scheduling policy = ???
arg = 20
1arg = 20
2arg = 20
thrd 2 schded
thrd 1 schded
As far as my understanding the threads are not getting scheduled in FIFO order.
my expected output is:
arg = 20
thrd 1 schded
1arg = 10
thrd 2 schded
2arg = 30
Scheduling policy = ??? - i printed this just to know what policy kernel is using.

is there any way i can get my expected out as actual, without modifying scheduling policy?

Please Help.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
void *fun1(void* );
void *fun2(void* );

int arg = 20;

int main(  void ) {
    pthread_t tid1,tid2;
    pthread_attr_t attr;

    int i; 
      int s = pthread_attr_getschedpolicy(&attr, &i);
      if (s != 0)
    handle_error_en(s, "pthread_attr_getschedpolicy");
    printf("Scheduling policy   = %s\n", 
    (i == SCHED_OTHER) ? "SCHED_OTHER" :
    (i == SCHED_FIFO)  ? "SCHED_FIFO" :
    (i == SCHED_RR)    ? "SCHED_RR" :
        "???");
    attr    
    printf(" arg = %d\n", arg);
    pthread_create(&tid1, NULL, fun1,NULL);
    printf(" 1arg = %d\n", arg);
    pthread_create(&tid2, NULL, fun2,NULL);
    printf(" 2arg = %d\n", arg);

    pthread_exit(&tid1);
    pthread_exit(&tid2);

return 0;
}
pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;

void * fun1( void *p)
{
    printf(" thrd 1 schded \n");
    pthread_mutex_lock(&mutex); 
    if (arg == 20)
        arg = 10;
    pthread_mutex_unlock(&mutex);   
}

void* fun2( void *p)
{
    printf(" thrd 2 schded \n");
    pthread_mutex_lock(&mutex); 
    if (arg == 10)
        arg = 30;
    pthread_mutex_unlock(&mutex);   
}

Output :

3
Contributors
5
Replies
4 Days
Discussion Span
9 Months Ago
Last Updated
6
Views
Gaiety
Junior Poster
135 posts since Sep 2009
Reputation Points: 13
Solved Threads: 3
Skill Endorsements: 0

OK you have a mutex to protect access to you data in the threads but you do not use it when access the data in main. This is an error whenever you access the data even for read you should always lock the mutex protecting its access.

It might be said that the read of the variable is atomic (i.e. can't be interrupted and is therefore safe without the mutex), it may be but you really can't be 100% sure what assembly code will be produced from your code particularly if you code is meant to be platform independent.

As to scheduling, the shecduler is not deterministict. If you need your threads to run in a specific order then you need to do it programatically. Various ways you might do this, only start thread 2 when thread 1 has finished, use some sort on sychronisation object (a semaphore for example) to hold up thread 2 until thread 1 has finished or design and write your program so that this type of synchronisation is not required.

Finally I do not thing pthread_exit does what you think it does. It exits the current thread with a return value (see http://linux.die.net/man/3/pthread_exit) it does not exit a thread identified by its id. You may want to be calling pthread_join though.

Banfa
Practically a Master Poster
695 posts since Mar 2010
Reputation Points: 508
Solved Threads: 109
Skill Endorsements: 5

To begin with, the attr object is not initialized, so calling pthread_attr_getschedpolicy on it is meaningless (thus your output of question marks).

As to scheduling, the shecduler is not deterministict.

Not so.

nezachem
Posting Shark
913 posts since Dec 2009
Reputation Points: 719
Solved Threads: 197
Skill Endorsements: 0

I have just modified the program.And now i am getting the out put what i am expecting.

I have few questions:

I wonder , does it always give the same result or it depends on how much functionality
the thread routine executes?

using pthread_join blocks the execution of the next statement(s) that is after join until the thread that is waiting on is finished?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;

void *fun1(void* );
void *fun2(void* );

int arg = 20;

int main(  void ) {
    pthread_t tid1,tid2;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    printf(" arg = %d\n", arg);
    pthread_create(&tid1, NULL, fun1,(void*)1);
    pthread_join(tid1,NULL);
    printf(" 1arg = %d\n", arg);

    pthread_create(&tid2, NULL, fun2,(void*)2);
    pthread_join(tid2,NULL);
    printf(" 2arg = %d\n", arg);

    printf("end\n");
    pthread_exit(NULL);

return 0;
}

void * fun1( void *p)
{
    int i;
    printf(" thrd %ld schded \n",(long) p);
    pthread_mutex_lock(&mutex); 
    if (arg == 20)
        arg = 10;
    pthread_mutex_unlock(&mutex);   
    for(i=0;i<10000000;i++);
    pthread_exit(NULL);
}

void* fun2( void *p)
{
    int i;
    printf(" thrd %ld schded \n",(long) p);
    pthread_mutex_lock(&mutex); 
    if (arg == 10)
        arg = 30;
    pthread_mutex_unlock(&mutex);   
    for(i=0;i<100000;i++);
    pthread_exit(NULL);
    pthread_exit(NULL);
}
Gaiety
Junior Poster
135 posts since Sep 2009
Reputation Points: 13
Solved Threads: 3
Skill Endorsements: 0

I wonder , does it always give the same result or it depends on how much functionality
the thread routine executes?

Can you please rephrase?

using pthread_join blocks the execution of the next statement(s) that is after join until the thread that is waiting on is finished?

Correct.

nezachem
Posting Shark
913 posts since Dec 2009
Reputation Points: 719
Solved Threads: 197
Skill Endorsements: 0

Can you please rephrase?

Sorry for confusing.
i got what i needed.

thanks a lot.

Gaiety
Junior Poster
135 posts since Sep 2009
Reputation Points: 13
Solved Threads: 3
Skill Endorsements: 0

This article has been dead for over three months: Start a new discussion instead

Post: Markdown Syntax: Formatting Help
 
You
 
© 2013 DaniWeb® LLC
Page rendered in 0.0918 seconds using 2.7MB