首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenMP生产者-消费者意想不到的结果

OpenMP生产者-消费者意想不到的结果
EN

Stack Overflow用户
提问于 2013-11-18 05:54:25
回答 1查看 2.4K关注 0票数 3

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

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

我的目标是同步生产者/消费者,以便每个生产者将产生下一个按字母顺序排列的字符,而每个使用者将按顺序打印放在缓冲区中的下一个字符。

这是我的密码:

代码语言:javascript
复制
#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);
       }
    }
}

这是输出:

代码语言:javascript
复制
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

那些没有打印字符的空行表明,我没有达到我应该实现的同步。我遗漏了什么?

提前感谢您的帮助或想法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-18 14:33:04

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

你看,我宣布了我的关键领域:

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

代码语言:javascript
复制
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);
    }
}

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

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

代码语言:javascript
复制
#pragma omp critical (CRIT)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20041030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档