user3021085
user3021085

Reputation: 417

pthread - conditional signal and wait

So I am currently trying out some things with pthread, but I keep running into problems that in my mind should work. In this, very unfinished, example I try to make manipulate 'x' amount of data with 'y' amount of threads. so I make 2 structs, 1 for the 'x' amount of data and one for the 'y' amount of threads. the struct for the thread has a pointer to struct for the data so I can switch those around without having recreate the thread or pass the entire dataset to the thread.

anyway I run into problem when I run the current version of the program. No thread pooling is done yet as I have not been able to get that far. what it should do is print out some information in a loop for each thread. it should start when I signal the condition. however the condition signal doesn`t seem to work properly as not all threads get activated...

I hope someone can help me!

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

#define NUM_THREADS     5    
#define NUM_LOOP        50



typedef struct infos {

   int real;    

} infos;



typedef struct thread_specs {

   infos          *infos;

   int thread_id;

   pthread_mutex_t mutex_condition;    
   pthread_cond_t  cond_wait;    

} thread_specs;




/* some trivial work to be done  but it should wait on the conditional wait*/
void *printtest(void *arg) {

   int i,sleep;
   thread_specs *thread_stuff= (thread_specs*)(arg);

    while (1) {
      pthread_cond_wait( &(thread_stuff->cond_wait) , &(thread_stuff->mutex_condition) );

         for (i=0;i<5;i++) {
            sleep=rand()%100000;
            printf("thread: %6i | loop: %2i\n",thread_stuff->thread_id,i); // thread_stuff->infos.real
            usleep(sleep);
         }
   }
}





int main () {

   pthread_t         threads[NUM_THREADS];

   infos             infostruct[NUM_LOOP];

   thread_specs      thread_info[NUM_THREADS];

   size_t            i;

   srand(time(0));

   for (i=0;i<NUM_THREADS;i++) {
      // setting the current loop into the thread_info struct and the info struct, later this would be more complex data but as an example it should suffice
      thread_info[i].thread_id=i;
      pthread_mutex_init(&(thread_info[i].mutex_condition), NULL);
      pthread_mutex_lock(&(thread_info[i].mutex_condition));
      infostruct[i].real=i;

      thread_info[i].infos=&infostruct[i];

   }


  // creating threads and passing a single index from the struct to it. later the infos struct pointer would be rotated to allow for different manipulation of data
   for (i=0;i<NUM_THREADS;i++) {
      if (pthread_create(&threads[i], NULL, printtest, &thread_info[i] )) {
         printf("ERROR creating thread");
      } else {
         printf("SUCCES creating thread #%i\n",i);
      }
   }

   printf("created all thread\n");

  // trying to signal all threads to start their work, make sure there mutex is unlocked so they are waiting for a the condition.
   for(i=0;i<NUM_THREADS;i++) {
      pthread_mutex_lock(&(thread_info[i].mutex_condition));
      pthread_mutex_unlock(&(thread_info[i].mutex_condition));
      pthread_cond_signal(&(thread_info[i].cond_wait));
   }

   printf("signaled condition\n");

   sleep(10);

   printf("\n!!DONE!!\n");

}  

Upvotes: 0

Views: 971

Answers (1)

Jens Gustedt
Jens Gustedt

Reputation: 78903

You are using the pthread_cond_wait completely wrong. It is only supposed to work when your thread holds the mutex. They whole trick is that pthread_cond_wait releases hold on the mutex temporarily during wait and reattributes it when coming back.

Also the call to pthread_cond_signal is best placed inside the critical section that holds the lock, not thereafter.

Upvotes: 1

Related Questions