每个线程一个布尔变量是多余的吗?

时间:2013-12-28 19:48:43

标签: c multithreading producer-consumer condition-variable

我编写了这段代码是为了更好地理解一个程序中的生产者消费者,我需要线程等待一个任务然后并行工作才能完成它。

我想知道我是否真的需要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;
}

0 个答案:

没有答案