pthreads和一些原始线程池的奇怪行为

时间:2014-04-01 08:44:42

标签: c linux multithreading pthreads

所以我虽然终于想出了如何做这些pthreads。基本上我的代码在for循环中打印出一些信息5次,它改变了传递的结构中的指针,因此在线程运行时可以更改不同的信息。无论如何它有时它的作用......有时它会打印出一个部分,或者有时会打印出乱码!od

我希望有人可以指出我的错误。

#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 {

   size_t               mainloop;

} infos;

typedef struct thread_specs {

   infos               *infos;

   size_t               thread_id;

   pthread_mutex_t      busy_mutex;
   pthread_cond_t       work_signal;

   pthread_barrier_t   *startup_barrier;

} thread_specs;


void *printtest(void *arg) {
   size_t i,sleep; 

   // casting passed information to struct
   thread_specs *thread_stuff= (thread_specs*)(arg);

   // accquiring mutex lock and wait for all threads to do the same
   pthread_mutex_lock(&(thread_stuff->busy_mutex));
   pthread_barrier_wait(thread_stuff->startup_barrier);

   while (1) {
         // wait for signal form main
         pthread_cond_wait(&(thread_stuff->work_signal), &(thread_stuff->busy_mutex));

         for (i=0;i<5;i++) {
            // do some stuff the random sleep is just the make it a little more non-deterministic
            sleep=rand()%100000;
            printf("main: %3i | thread: %3i | loop: %2i\n",thread_stuff->infos->mainloop,thread_stuff->thread_id,i); // thread_stuff->infos.real
            usleep(sleep);
         }

   }

}


int main () {

   // init pthread data types and the structs used.
   pthread_t         threads[NUM_THREADS];

   infos             infostruct[NUM_LOOP];
   thread_specs      thread_info[NUM_THREADS];
   pthread_barrier_t init_barrier;

   size_t            i,j;

   srand(time(0));

   printf("\n\n");

   // initialize barrier used to sync threads and main
   pthread_barrier_init(&init_barrier,NULL,NUM_THREADS+1);

   // pthread creation loop, passes the barrier as a pointer to the thread_specs struct also initializes the mutex and condition
   for (i=0;i<NUM_THREADS;i++) {
      thread_info[i].thread_id=i;
      thread_info[i].startup_barrier=&init_barrier;
      pthread_mutex_init(&(thread_info[i].busy_mutex), NULL);
      pthread_cond_init(&(thread_info[i].work_signal), NULL);

      if (pthread_create(&threads[i], NULL, printtest, &thread_info[i] )) {
         printf("ERROR creating thread");
      } else {
         printf("SUCCES creating thread #%i\n",i);
      }

   }

   // wait for all threads to have acquired ownership of the mutex

   pthread_barrier_wait(&init_barrier);

   printf("created all threads\n");


   // loop to iterate of the loop to check if threads are busy and assign work to them if they arent. 
   // the thread MUST be busy if it currently holds the busy_mutex mutex, if it doesn`t it is waiting on the condition

   i=0;while(i<NUM_LOOP) {

      for (j=0;j<NUM_THREADS;j++) {

         if ((pthread_mutex_trylock(&(thread_info[j].busy_mutex)))==0) {
            infostruct[i].mainloop=i;
            thread_info[j].infos=&infostruct[i];
            pthread_cond_signal(&(thread_info[j].work_signal));
            pthread_mutex_unlock(&(thread_info[j].busy_mutex));
            ++i;
         }

      }

   }

   // crude wait to wait for all threads to finish their last work
   for (j=0;j<NUM_THREADS;j++) {
      pthread_mutex_lock(&(thread_info[j].busy_mutex));
      pthread_mutex_unlock(&(thread_info[j].busy_mutex));
   }

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

   exit(0);
}  

2 个答案:

答案 0 :(得分:0)

  

有时会打印出一部分,有时会打印出乱码!

printf() size_t使用"zu"

答案 1 :(得分:0)

对于只打印部分的时间可能是因为当主线程执行trylock()并且相应的线程可能未到达pthread_cond_wait()发布的点时会出现竞争互斥体。

在这种情况下,线程的条件变量永远不会发出信号。