Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多生产者消费者执行的效率_C++_Multithreading_Mutex_Semaphore_Producer Consumer - Fatal编程技术网

C++ 多生产者消费者执行的效率

C++ 多生产者消费者执行的效率,c++,multithreading,mutex,semaphore,producer-consumer,C++,Multithreading,Mutex,Semaphore,Producer Consumer,我试图与多个生产者和消费者一起编写代码。我为生产者和消费者创建了多线程,并使用信号量进行同步。代码在单个生产者和消费者之间运行良好 我面临的问题是,在程序执行一段时间后,只有consumer1和producer1参与了这个过程。我无法理解其他生产商和消费者的遭遇 我还想知道如何使多生产者消费者问题有效?在所有生产者和消费者分别获得平等的生产和消费机会的意义上,是否有效? C++代码(包括很多C): #包括 #包括 #包括 #包括 #包括 使用名称空间std; 扫描电镜不为空; 扫描电镜全; in

我试图与多个生产者和消费者一起编写代码。我为生产者和消费者创建了多线程,并使用信号量进行同步。代码在单个生产者和消费者之间运行良好

我面临的问题是,在程序执行一段时间后,只有consumer1和producer1参与了这个过程。我无法理解其他生产商和消费者的遭遇

我还想知道如何使多生产者消费者问题有效?在所有生产者和消费者分别获得平等的生产和消费机会的意义上,是否有效? C++代码(包括很多C):

#包括
#包括
#包括
#包括
#包括
使用名称空间std;
扫描电镜不为空;
扫描电镜全;
int-cnt=0;
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
队列q;
无效*制作人(无效*a)
{   
int*num=(int*)a;
而(1){
sem_等待(&empty);
pthread_mutex_lock(&mutex);
cnt=cnt+1;
q、 推送(cnt);

简短的回答

实际上,线程执行的机会是均等的,但它们只是打印出一个不是它们的标识符

详细说明

在每个线程中都保留一个指向线程编号的指针。保存的是指向该值的指针,而不是该值本身。因此所有线程都指向同一个计数器,希望在那里找到自己的标识符

每次访问
*num
时,您所访问的不是启动线程时
i
的值,而是它的当前值

不幸的是,在
main()的每个循环中
,您将重用变量
i
。因此,在最后一个循环中,您将
i
设置回
0
,并等待第一个线程加入。但所有这些线程都将永远循环,因此循环几乎没有机会超过此初始0值。因此,每个线程都认为此时的数字
*num+1
为1预兆

请注意,正如有人在评论中指出的那样,您创建了一个争用条件:所有使用者线程和生产者线程都会取消对指针的引用,访问互斥保护区域中的同一个变量。这是可以的。但是当他们读取变量时,主线程仍然可以很高兴地在任何lo之外更改共享变量这绝对是一种种族风险

解决方法

将允许您通过walue传递
i
,这样每个线程都有自己的is id的未更改副本

对于pthreads,您必须传递一个指向某个值的指针。不幸的是,即使您在线程开始时对所指向的值进行本地复制,您仍然会处于争用状态


观察哪个线程真正在做工作的一个快速解决方法是打印输出的结果(参见如何做)或者将ID存储在一个int数组中,并将每个线程的地址传递给该数组中的一个唯一元素。

查看您传递给pthRead创建的参数,以及如何在线程函数中使用该信息。考虑是否存在竞争条件。考虑传递<代码> I<代码>对传递<代码的影响。>和<代码> >任何理由证明使用OS特定的代码> ptho> <代码>代替标准<代码>代码::线程< /COD> >克里斯多夫:因为我没有学习C++中的线程,所以我使用了C版本。@ DavidThomas:当我使用互斥体时,如何才能创建竞争条件,每次只能允许线程访问关键的原因?所有10个线程都会收到指向同一内存位置
i
的指针。在创建线程时,此内存位置正在更改。读取内存位置的线程与修改内存位置的main()线程之间存在竞争条件。如果显式将i的值传递给每个线程(而不是指向I的指针)您将不会共享内存位置并消除竞争。thread_join将如何更改初始值?我不明白?@ShivamMitra thread_join不会更改任何内容,但您会在以
开始的循环中执行此操作(i=0;
不幸的是,所有num指针指向的都是同一个i。有没有关于如何打印哪个线程产生或消费的建议?@ShivamMitra它在我的编辑中(包括关于如何打印
pthread\u t
的超链接):我已经更新了代码。是否检查竞争条件是否仍然存在?我想是的。但是输出没有显示任何竞争条件。
#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);
    }
}