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 :

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.

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.

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);
}

Edited 4 Years Ago by Gaiety: forgtot to paste the code

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.

Can you please rephrase?

Sorry for confusing.
i got what i needed.

thanks a lot.

This article has been dead for over six months. Start a new discussion instead.