4

When a thread call pthread_cond_signal(), Unix network programming said pthread_cond_signal() just would nofity just one thread, beacause it isn't pthread_cond_broadcast(). It means there is no race condition. However, the book does not say which thread would be notified, and how. Does the function wake thread randomly?

Howo
  • 99
  • 3
  • it is bad habit to try to figure out things like this or predict this like this, it is the job of the SCHEDULER to choose which thread to wake up whenever you call `pthread_cond_signal`, the thread to wake up must have the same function signature as `pthread_cond_signal` in respect of the condition variable – 0.sh Mar 14 '18 at 19:29
  • 1
    ...In other words, if two threads in your program await the same condition, they should be interchangeable: Your code should be designed so that it does not matter which one of them handles the event. – Solomon Slow Mar 14 '18 at 20:12

3 Answers3

6

Straight from the man:

If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order in which threads are unblocked.

The "scheduling policy" is the order the operating systems decided on. It's one of the four listed in the below link, but you don't really know (without some impressive hackery at least) which one is "first" anyway. It shouldn't matter either - all threads waiting on the condition should be equally ready to continue - otherwise you have a design problem.

Scheduling policies in Linux Kernel has a bit of discussion on some linux policies, and you can google from there if it's important.

kabanus
  • 24,623
  • 6
  • 41
  • 74
2

See below my example which will help you to understand about it very clearly.I am using 3 mutexs and 3 conditions. With the below example you can synchronized or prioritize any number of threads in C. If you see the first thread here it locked mutex lock1 and waiting on cond1, likewise second thread locked mutex lock2 and waits on condition cond2 and 3rd thread locked mutex lock3 and waits on condition cond3. This is the current situation of all the threads after they are being created and now all the threads are waiting for a signal to execute further on its condition variable. In the main thread (i.e. main function, every program has one main thread, in C/C++ this main thread created automatically by operating system once control pass to the main method by kernal) we are calling pthread_cond_signal(&cond1); once this system call done thread1 who was waiting on cond1 will be release and it will start executing. Once it finished with its task it will call pthread_cond_signal(&cond3); now thread who was waiting on condition cond3 i.e. thread3 will be release and it will start execute and will call pthread_cond_signal(&cond2); which will release the thread who is waiting on condition cond2 i.e. in this case thread2.

include<pthread.h>

pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock3 = PTHREAD_MUTEX_INITIALIZER;

int TRUE = 1;

void print(char *p)
{
  printf("%s",p);
}

void * threadMethod1(void *arg)
{
  printf("In thread1\n");
  do{
    pthread_mutex_lock(&lock1);
    pthread_cond_wait(&cond1, &lock1);
    print("I am thread 1st\n");
    pthread_cond_signal(&cond3);/* Now allow 3rd thread to process */
    pthread_mutex_unlock(&lock1);
  }while(TRUE);
  pthread_exit(NULL);
}

void * threadMethod2(void *arg)
{
  printf("In thread2\n");
  do
  {
    pthread_mutex_lock(&lock2);
    pthread_cond_wait(&cond2, &lock2);
    print("I am thread 2nd\n");
    pthread_cond_signal(&cond1);
    pthread_mutex_unlock(&lock2);
  }while(TRUE);
  pthread_exit(NULL);
}

void * threadMethod3(void *arg)
{
  printf("In thread3\n");
  do
  {
    pthread_mutex_lock(&lock3);
    pthread_cond_wait(&cond3, &lock3);
    print("I am thread 3rd\n");
    pthread_cond_signal(&cond2);
    pthread_mutex_unlock(&lock3);
  }while(TRUE);
  pthread_exit(NULL);
}

int main(void)
{
  pthread_t tid1, tid2, tid3;
  int i = 0;

  printf("Before creating the threads\n");
  if( pthread_create(&tid1, NULL, threadMethod1, NULL) != 0 )
        printf("Failed to create thread1\n");
  if( pthread_create(&tid2, NULL, threadMethod2, NULL) != 0 )
        printf("Failed to create thread2\n");
  if( pthread_create(&tid3, NULL, threadMethod3, NULL) != 0 )
        printf("Failed to create thread3\n");
  pthread_cond_signal(&cond1);/* Now allow first thread to process first */


  sleep(1);
  TRUE = 0;/* Stop all the thread */
  sleep(3);

 /* this is how we join thread before exit from a system */
  /*  
  pthread_join(tid1,NULL);
  pthread_join(tid2,NULL);
  pthread_join(tid3,NULL);*/

 exit(0);
}
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
0

Yes, it will wake one thread seemingly randomly. It's up to the operating system to decide which one will be woken.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621