我编写了这段代码是为了更好地理解一个程序中的生产者消费者,我需要线程等待一个任务然后并行工作才能完成它。
我想知道我是否真的需要conditionMet
整数变量的数组?
我可以不用一个整数做同样的事吗?
我有什么办法可以简化代码吗? 我的目标是允许主线程将任务交给其他线程。
由于这只是骨架,我想知道是否有办法简化它?
#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define NTHREADS 7
#define RUN_N_TIMES 3
pthread_cond_t new_task_available = PTHREAD_COND_INITIALIZER;
pthread_cond_t task_complete = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
volatile int producerCond = 0;
volatile int conditionMet[NTHREADS] = {};
volatile int no_more_tasks = 0;
volatile int mini_tasks_complete = - NTHREADS;
void do_work(unsigned int* current_level){
++*current_level;
printf("Thread %u has completed %u units of work.\nIt was #%d to complete it's task this round..\n", (unsigned int)pthread_self(), *current_level, mini_tasks_complete);
}
void *threadfunc(void *parm)
{
int* thread_cond;
unsigned int level = 0;
thread_cond = (int*)parm;
while(!no_more_tasks){
pthread_mutex_lock(&mutex);
++mini_tasks_complete;
if(mini_tasks_complete == NTHREADS){
producerCond = 1;
pthread_cond_signal(&task_complete);
}
threads_waiting++;
*thread_cond = 0;
while (!*thread_cond) {
pthread_cond_wait(&new_task_available, &mutex);
if(no_more_tasks)
{
pthread_mutex_unlock(&mutex);
return NULL;
}
}
pthread_mutex_unlock(&mutex);
do_work(&level);
}
return NULL;
}
void reset_cond(int val){
int i;
for (i=0; i<NTHREADS; ++i)
conditionMet[i] = val;
}
int main(int argc, char **argv)
{
int i;
pthread_t threadid[NTHREADS];
for(i=0; i < NTHREADS; ++i) {
pthread_create(&threadid[i], NULL, threadfunc, &(conditionMet[i]));
}
while(threads_waiting < NTHREADS)
sleep(1); /* Sleep is not a very robust way to serialize threads */
/* The condition has occured. Set the flag and wake up any waiting threads */
printf("Waking up all waiting threads " "#RUN_N_TIMES" " times...\n");
for(i = 0; i < RUN_N_TIMES; i++){
pthread_mutex_lock(&mutex);
mini_tasks_complete = 0;
printf("New tasks available.\n");
sleep(1);
reset_cond(1);
pthread_cond_broadcast(&new_task_available);
producerCond = 0;
while (!producerCond) {
printf("Main waiting\n");
pthread_cond_wait(&task_complete, &mutex);
}
pthread_mutex_unlock(&mutex);
}
no_more_tasks = 1;
pthread_mutex_lock(&mutex);
mini_tasks_complete = 0;
printf("Go home everybody!\n");
pthread_cond_broadcast(&new_task_available);
pthread_mutex_unlock(&mutex);
printf("Wait for threads and cleanup\n");
for (i=0; i<NTHREADS; ++i) {
pthread_join(threadid[i], NULL);
}
pthread_cond_destroy(&new_task_available);
pthread_cond_destroy(&task_complete);
pthread_mutex_destroy(&mutex);
printf("Main done\n");
return 0;
}