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

C pthreads和一些原始线程池的奇怪行为,c,linux,multithreading,pthreads,C,Linux,Multithreading,Pthreads,所以我想我终于想出了如何做这些pthread。基本上,我的代码在for循环中打印出一些信息5次,它会更改传递的结构中的指针,以便在线程运行时可以更改不同的信息。不管怎么说,有时它是有效的。。。有时它打印出一个零件,有时它打印出胡言乱语!od 我希望有人能指出我的错误 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <

所以我想我终于想出了如何做这些pthread。基本上,我的代码在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);
}  
#包括
#包括
#包括
#包括
#包括
#定义NUM_线程5
#定义NUM_循环50
类型定义结构信息{
主回路的尺寸;
}信息系统;
typedef结构螺纹规格{
infos*infos;
螺纹id的尺寸;
pthread_mutex_t busy_mutex;
pthread_cond_t work_信号;
pthread_barrier_t*启动_barrier;
}螺纹规格;
void*打印测试(void*arg){
大小,睡眠;
//强制转换将信息传递给struct
线程规格*线程规格=(线程规格*)(arg);
//正在获取互斥锁并等待所有线程执行相同操作
pthread_mutex_lock(&(thread_stuff->busy_mutex));
pthread\u barrier\u wait(线程\u stuff->启动\u barrier);
而(1){
//等待主信号机的信号
pthread_cond_wait(&(thread_stuff->work_signal),&(thread_stuff->busy_mutex));
对于(i=0;iinfo->mainloop,thread\u stuff->thread\u id,i);//thread\u stuff->infos.real
usleep(睡眠);
}
}
}
int main(){
//init pthread数据类型和使用的结构。
pthread_t threads[NUM_threads];
infos infostruct[NUM_LOOP];
线程规格线程信息[线程数];
pthread_barrier_t init_barrier;
尺寸i,j;
srand(时间(0));
printf(“\n\n”);
//初始化用于同步线程和主线程的屏障
pthread_barrier_init(&init_barrier,NULL,NUM_THREADS+1);
//pthread creation循环,将屏障作为指向thread_specs结构的指针传递,并初始化互斥锁和条件
对于(i=0;i
有时它打印出一个零件,有时它打印出胡言乱语


要想
printf()
size\t
使用
“zu”
,在只打印部分的时候,可能是因为主线程执行
trylock()
时存在争用,而相应的线程可能尚未达到
pthread\u cond\u wait()
释放互斥锁的点


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

也许你可以发布一些预期的输出和一些胡言乱语。不,循环会重复。问题是信号不会立即唤醒线程。循环在唤醒线程之前多次发信号是合法的。我想我不是完全清楚r您看到了什么问题。我知道有一个外循环为主线程提供了向以前锁定的线程发送信号的能力,但是这意味着当以前锁定的线程收到信号时,
I
将增加,因此一些
I
的实例将不会被某个线程打印出来s、 可能吧。或者至少,在我看来是这样的(我还没有编译和运行你的程序)。我仍然不确定到底是什么乱码。乱码很可能是因为我没有使用正确的printf参数。从那以后我就没有见过它。你是对的,跳过了一些“I”,这就是问题所在。我无法真正发布整个代码输出,因为它可能太长了。但是我已经在c编程板上发布了包括输出,我现在知道我的问题了。但我想我会用链表格式重做它。