Only one consumer works fine, but multiple consumers will crash, I am wondering why.
#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <queue>
using namespace std;
pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_qs_notempty = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_qs_notfull = PTHREAD_COND_INITIALIZER;
queue<string> qs;
void *
producer(void *arg)
{
static vector<string> vs{"a ","b ","c ","d ","e "};
static int idx = 0;
while(1){
pthread_mutex_lock(&g_mutex);
if(qs.size()==5)//full
pthread_cond_wait(&g_qs_notfull,&g_mutex);
qs.push(vs[idx]);
idx = (idx+1)%5;
pthread_cond_signal(&g_qs_notempty);
pthread_mutex_unlock(&g_mutex);
}
return NULL;
}
void *
consumer(void *arg)
{
while(1){
pthread_mutex_lock(&g_mutex);
if(qs.empty())
pthread_cond_wait(&g_qs_notempty,&g_mutex);
cout<<qs.front();
qs.pop();
pthread_cond_signal(&g_qs_notfull);
pthread_mutex_unlock(&g_mutex);
}
return NULL;
}
int main()
{
struct thread_info *tinfo;
pthread_attr_t attr;
pthread_t thread_id;
pthread_attr_init(&attr);
pthread_create(&thread_id, &attr, &producer, 0);
pthread_create(&thread_id, &attr, &consumer, 0);
pthread_create(&thread_id, &attr, &consumer, 0); //adding this line will crash
pthread_exit(0);
}
It is not guaranteed that _signal()
wakes up only a single thread.
So you must recheck your condition upon wakeup. A simply way to fix your code is to switch the if
for while
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.