【发布时间】:2016-07-03 14:55:09
【问题描述】:
我试图编写一个包含多个生产者和消费者的代码。我为生产者和消费者创建了多线程,并使用信号量进行同步。该代码适用于单个生产者和消费者。
我面临的问题是,在程序执行一段时间后,只有消费者 1 和生产者 1 参与了该过程。我无法理解其他生产者和消费者发生了什么。
我也想知道如何使多生产者消费者问题有效?从所有生产者和消费者分别获得平等的生产和消费机会的意义上说是有效的吗? C++代码(包含很多C):
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <queue>
using namespace std;
sem_t empty;
sem_t full;
int cnt = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
queue<int> q;
void *producer(void *a)
{
int *num = (int *)a;
while(1) {
sem_wait(&empty);
pthread_mutex_lock(&mutex);
cnt = cnt+1;
q.push(cnt);
cout<<cnt<<" item produced by producer "<<(*num+1)<<endl;
pthread_mutex_unlock(&mutex);
sem_post(&full);
sleep(1);
}
}
void *consumer(void *a)
{
int *num = (int *)a;
while(1) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
cout<<q.front()<<" item consumed by consumer "<<(*num+1)<<endl;
q.pop();
pthread_mutex_unlock(&mutex);
sem_post(&empty);
sleep(1);
}
}
int main()
{
pthread_t p[5];
pthread_t c[5];
sem_init(&empty,0,5);
sem_init(&full,0,0);
int i;
for(i = 0; i < 5; i++) {
pthread_create(&p[i],NULL,producer,(void *)(&i));
}
for(i = 0; i < 5; i++) {
pthread_create(&c[i],NULL,consumer,(void *)(&i));
}
for(i = 0; i < 5; i++) {
pthread_join(p[i],NULL);
pthread_join(c[i],NULL);
}
}
更新代码:
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <queue>
#include <map>
using namespace std;
sem_t empty;
sem_t full;
int cnt = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
map<pthread_t,int> mc,mp;
queue<int> q;
void *producer(void *a)
{
while(1) {
sem_wait(&empty);
pthread_mutex_lock(&mutex);
cnt = cnt+1;
q.push(cnt);
cout<<cnt<<" item produced by producer "<<mp[pthread_self()]<<endl;
pthread_mutex_unlock(&mutex);
sem_post(&full);
sleep(1);
}
}
void *consumer(void *a)
{
while(1) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
cout<<q.front()<<" item consumed by consumer "<<mc[pthread_self()]<<endl;
q.pop();
pthread_mutex_unlock(&mutex);
sem_post(&empty);
sleep(1);
}
}
int main()
{
pthread_t p[5];
pthread_t c[5];
sem_init(&empty,0,5);
sem_init(&full,0,0);
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < 5; i++) {
pthread_create(&p[i],NULL,producer,NULL);
pthread_create(&c[i],NULL,consumer,NULL);
mc[c[i]] = i+1;
mp[p[i]] = i+1;
}
pthread_mutex_unlock(&mutex);
for(i = 0; i < 5; i++) {
pthread_join(p[i],NULL);
pthread_join(c[i],NULL);
}
}
【问题讨论】:
-
查看您传递给 pthread_create 的参数以及您如何在线程函数中使用该信息。考虑是否存在竞争条件。考虑通过
i与通过&i的影响。 -
有任何理由证明使用操作系统特定的
pthread而不是标准的std::thread吗? -
@Christophe : 由于我没有学过c++的线程,所以我用的是c版本的。
-
@DavidThomas : 当我使用互斥锁一次只允许线程访问关键原因时,如何创建竞争条件?
-
@shivammitra。您的所有 10 个线程都收到指向同一内存位置
i的指针。在创建线程时正在更改此内存位置。读取内存位置的线程和修改内存位置的 main() 之间存在竞争条件。如果您将 i 的值显式传递给每个线程(而不是指向 I 的指针),您将不会共享内存位置并消除竞争。
标签: c++ multithreading mutex semaphore producer-consumer