【问题标题】:How to synchronize threads (consumer/producer)如何同步线程(消费者/生产者)
【发布时间】:2013-05-20 00:55:17
【问题描述】:

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <queue>
using namespace std;

queue<int> myqueue;

pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

void *consumer(void*);
void *producer(void*);

#define COUNT_DONE 10
int count = 0;

main()
{
   pthread_t thread1, thread2;

   pthread_create( &thread2, NULL, &consumer, NULL);
   pthread_create( &thread1, NULL, &producer, NULL);

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

   printf("Final count: %d\n",count);

   system("PAUSE");
   return EXIT_SUCCESS;
}

void *consumer(void*)
{
   for(;;)
   {
      // Lock mutex and then wait for signal to relase mutex
      printf("consumer mutex lock \n");
      pthread_mutex_lock( &count_mutex );
      printf("consumer mutex locked\n");

      // Wait while functionCount2() operates on count
      // mutex unlocked if condition varialbe in functionCount2() signaled.
      printf("consumer wait\n");
      pthread_cond_wait( &condition_var, &count_mutex );
      printf("consumer condition woke up\n");
      myqueue.pop();count--;
      printf("Counter value consumer: %d\n",count);

      printf("consumer mutex unlock\n");
      pthread_mutex_unlock( &count_mutex );

      if(count >= COUNT_DONE) return(NULL);
    }
}

void * producer(void*)
{
    for(;;)
    {
       printf("producer mutex lock\n");
       pthread_mutex_lock( &count_mutex );
       printf("producer mutex locked\n");

       if( count < COUNT_DONE)
       {
           myqueue.push(1);
           count++;
           printf("Counter value producer: %d\n",count);
           printf("producer signal\n");
           pthread_cond_signal( &condition_var );
       }

       printf("producer mutex unlock\n");
       pthread_mutex_unlock( &count_mutex );

       if(count >= COUNT_DONE) return(NULL);

       Sleep(5000);
    }

}

当消费者线程首先使用互斥锁时,此示例运行良好。但是当生产者线程最初获取互斥体时,队列中总会有 1 个整数,消费者无法弹出。

如何让消费者线程在生产者之前先获取互斥锁。

注意:我正在寻找一种比在另一个线程之前启动一个线程更好的方法。

谢谢,

【问题讨论】:

    标签: c++ pthreads condition-variable


    【解决方案1】:

    我看到的一个问题是您的消费者实际上并没有检查要做的工作,它只是盲目地从队列中弹出。

    我看到的第二个问题是你增加一个计数并减少另一个计数,那么你如何达到终止条件?

    从消费者中取出忍者“count--”,它应该可以工作。不过,您可能希望在消费者内部执行以下操作:

    // Wait for producer to do its thing and tell us there is work to do.
    while ( myqueue.empty() ) {
        pthread_cond_wait(&condition_var, &count_mutex);
    }
    // we've been told there's work to do with the queue,
    // and we know there's something ON the queue.
    // consume the entire queue.
    while ( !myqueue.empty() ) {
      myqueue.pop();
    }
    
    // treat count as protected by the mutex, so hoist this test into the lock.
    bool workDone = (count >= COUNT_DONE);
    pthread_mutex_unlock(&count_mutex);
    
    if(workDone)
        return break;
    

    编辑:消费者的首选版本:

    bool workDone = false;
    while(workDone == false)
    {
        // Lock mutex and then wait for signal to relase mutex
        pthread_mutex_lock( &count_mutex );
    
        // Wait for producer to do its thing and tell us there is work to do.
        while ( myqueue.empty() )
        pthread_cond_wait( &condition_var, &count_mutex );
    
        // we've been told there's work to do with the queue,
        // and we know there's something ON the queue.
        // consume the entire queue.
        while ( myqueue.empty() == false ) {
            myqueue.pop();
        }
    
        // count is protected by the lock so check if we're done before we unlock.
        workDone = (count >= COUNT_DONE);
        pthread_mutex_unlock( &count_mutex );
    
    }
    return NULL;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 2017-02-01
      • 2012-04-30
      相关资源
      最近更新 更多