不使用flag变量的线程同步

时间:2015-02-26 16:54:23

标签: c multithreading pthreads

我已根据我的任务通过pthread实现了生产者 - 消费者线程同步问题,但我的老师拒绝说使用flag变量是不可接受的,因为它是低效的方式。任何人都可以建议如何在不使用flag变量的情况下实现它。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

void *consumer();
void *producer();
int  count = 0;
#define COUNT_DONE  10
int flag=0;
main()
{
   pthread_t thread1, thread2;
   pthread_create( &thread1, NULL, &producer, NULL);
   pthread_create( &thread2, NULL, &consumer,NULL);

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   exit(EXIT_SUCCESS);
}

void *consumer()
{
   for(;;)
   {
      // Lock mutex and then wait for signal to relase mutex
      pthread_mutex_lock( &count_mutex );

      pthread_cond_wait( &condition_var, &count_mutex );

      while (count!=0)
      { 
      count--;
      printf("Counter value consumer: %d\n",count);
      }
      pthread_mutex_unlock( &count_mutex );

      if(count == 0) 
      {
      return NULL; 

      } 
    }
}

void *producer()
{
    for(;;)
    {
       pthread_mutex_lock( &count_mutex );

       if( count==COUNT_DONE  )
       {
          flag=1;
         pthread_cond_signal( &condition_var );

       }
       else if(flag==0)
       {
          count++;
          printf("Counter value producer: %d\n",count);
       }

       pthread_mutex_unlock( &count_mutex );
          if(count==0) return (NULL);

    }

}

2 个答案:

答案 0 :(得分:0)

鉴于消费者线程在通过条件变量发出信号之前被阻塞,它在检查之后才检查变量count,生成器在count递增{{}}之前不会发出信号{1}},并且生产者之后不再增加COUNT_DONE,此版本的count更简单地产生相同的结果:

producer()

虽然这个版本不会等待消费者在它自己完成之前完成,但如果消费者在不消耗void *producer() { pthread_mutex_lock( &count_mutex ); for(; count < COUNT_DONE; count++) { printf("Counter value producer: %d\n",count); } pthread_cond_signal( &condition_var ); pthread_mutex_unlock( &count_mutex ); return NULL; } 的情况下死亡,它也不会进入无限循环。

答案 1 :(得分:0)

在传统的生产者消费者解决方案中,将有两个条件变量来表示生成和消费线程。修改后的实现如下。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var_produce   = PTHREAD_COND_INITIALIZER;
pthread_cond_t  condition_var_consume   = PTHREAD_COND_INITIALIZER;

void *consumer();
void *producer();
int  count = 0;
#define COUNT_DONE  10
main()
{
   pthread_t thread1, thread2;
   pthread_create( &thread1, NULL, &producer, NULL);
   pthread_create( &thread2, NULL, &consumer,NULL);

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   exit(EXIT_SUCCESS);
}

void *consumer()
{
    static int numberOfIterations = 1;
    while(numberOfIterations--);
    {
      pthread_mutex_lock( &count_mutex );

      while(count!=COUNT_DONE)
              pthread_cond_wait( &condition_var_consume, &count_mutex );

      while (count!=0)
      {
              printf("Counter value consumer: %d\n",count);
              count--;
      }
      pthread_cond_signal(&condition_var_produce);
      pthread_mutex_unlock( &count_mutex );

      if(count == 0)
      {
        return NULL;
      }
    }
}

void *producer()
{
    static int numberOfIterations = 1;
    while(numberOfIterations--);
    {
       pthread_mutex_lock( &count_mutex );

       while (count!=0)
              pthread_cond_wait( &condition_var_produce, &count_mutex );

       while(count!=COUNT_DONE  )
        {
             count++;
             printf("Counter value producer: %d\n",count);
        }

         pthread_cond_signal( &condition_var_consume );
         pthread_mutex_unlock( &count_mutex );
    }

}