簡體   English   中英

如何同步線程(消費者/生產者)

[英]How to synchronize threads (consumer/producer)

我有以下代碼:

#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個整數,消費者無法彈出該整數。

我如何讓使用者線程在產生者之前先獲取互斥體。

注意:我正在尋找一種比在另一個線程之前啟動一個線程更好的方法。

謝謝,

我看到的一個問題是,您的消費者實際上並沒有檢查要完成的工作,只是從隊列中盲目彈出。

我看到的第二個問題是您在一個中增加計數而在另一個中減少計數,那么您如何達到終止條件?

將忍者“計數-”從消費者中刪除,它應該可以工作。 不過,您可能想在使用者內部執行以下操作:

// 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM