gpt4 book ai didi

c - OpenMP 生产者-消费者意外结果

转载 作者:行者123 更新时间:2023-12-04 09:33:38 25 4
gpt4 key购买 nike

我正在处理一个简单的生产者-消费者问题,使用 C 中的 OpenMP。

我的程序创建了 4 个线程,其中两个是消费者,两个是生产者。每个生产者将一个字符放入缓冲区,消费者只需打印该字符即可。

我的目标是同步生产者/消费者,以便每个生产者将生产字母表中的下一个有序字符,并且每个消费者将打印放置在缓冲区中的下一个有序字符。

这是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <omp.h>

#define SIZE 5
#define NUMITER 26


char buffer[SIZE];
int nextin = 0;
int nextout = 0;
int count = 0;
int empty = 1;
int full = 0;
int i,j;

void put(char item)
{
buffer[nextin] = item;
nextin = (nextin + 1) % SIZE;

count++;
if (count == SIZE)
full = 1;
if (count == 1) // buffer was empty
empty = 0;
}


void producer(int tid)
{
char item;
while( i < NUMITER)
{
#pragma omp critical
{
item = 'A' + (i % 26);
put(item);
i++;
printf("%d Producing %c ...\n",tid, item);
}
sleep(1);
}
}


char get()
{
char item;

item = buffer[nextout];
nextout = (nextout + 1) % SIZE;
count--;
if (count == 0) // buffer is empty
empty = 1;
if (count == (SIZE-1))
// buffer was full
full = 0;
return item;
}


void consumer(int tid)
{
char item;
while(j < NUMITER )
{
#pragma omp critical
{
j++;
item = get();
printf("%d ...Consuming %c\n",tid, item);
}
sleep(1);
}
}

int main()
{
int tid;
i=j=0;
#pragma omp parallel firstprivate(i,j) private(tid) num_threads(4)
{
tid=omp_get_thread_num();

if(tid%2==1)
{
producer(tid);
}
else
{
consumer(tid);
}
}
}

这是输出:

0 Producing A ...
2 Producing B ...
1 ...Consuming A
3 ...Consuming B
1 ...Consuming <---- notice empty
0 Producing C ...
3 ...Consuming <---- notice empty
2 Producing D ...
2 Producing E ...
3 ...Consuming E
0 Producing F ...
1 ...Consuming F
2 Producing G ...
3 ...Consuming G
0 Producing H ...
1 ...Consuming H
3 ...Consuming D
2 Producing I ...
0 Producing J ...
1 ...Consuming J
3 ...Consuming F
2 Producing K ...
0 Producing L ...
1 ...Consuming L
3 ...Consuming H
2 Producing M ...
0 Producing N ...
1 ...Consuming N
3 ...Consuming J
2 Producing O ...
0 Producing P ...
1 ...Consuming P
3 ...Consuming L
2 Producing Q ...
0 Producing R ...
1 ...Consuming R
2 Producing S ...
3 ...Consuming S
0 Producing T ...
1 ...Consuming T
3 ...Consuming P
2 Producing U ...
0 Producing V ...
1 ...Consuming V
2 Producing W ...
3 ...Consuming W
0 Producing X ...
1 ...Consuming X
2 Producing Y ...
3 ...Consuming Y
0 Producing Z ...
1 ...Consuming Z

那些没有打印字符的空行表明我没有实现我应该实现的同步。我错过了什么?

预先感谢您提供任何帮助或想法。

最佳答案

所以@Jlghtuse 是正确的,存在数据竞争,这是因为关键区域的错误声明。

你看我声明了我的关键区域:

void consumer(int tid)
{
char item;
while(j < NUMITER )
{
#pragma omp critical
{
j++;
item = get();
printf("%d ...Consuming %c\n",tid, item);
}
sleep(1);
}
}

void producer(int tid)
{
char item;
while( i < NUMITER)
{
#pragma omp critical
{
item = 'A' + (i % 26);
put(item);
i++;
printf("%d Producing %c ...\n",tid, item);
}
sleep(1);
}
}

这导致消费者无法访问其他消费者的关键区域,但生产者可以访问,反之亦然。解决方案相当简单,我只需为关键区域添加一个通用名称,现在消费者的关键区域对生产者也至关重要,反之亦然。

这是声明关键区域的正确代码:

#pragma omp critical (CRIT)

关于c - OpenMP 生产者-消费者意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20041030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com