【问题标题】:producer consumer (using Monitor) code is not working when sleep() is used?使用 sleep() 时生产者消费者(使用监视器)代码不起作用?
【发布时间】:2023-03-03 04:19:01
【问题描述】:
#include<bits/stdc++.h>
#include<pthread.h>
#include<unistd.h>
#define MAX 10
using namespace std;
class BoundedBuffer
{
private:
  int buffer[MAX];
  int fill, use;
  int fullEntries;
  pthread_mutex_t monitor;  // monitor lock
  pthread_cond_t empty;
  pthread_cond_t full;
public:
  BoundedBuffer ()
  {
    use = fill = fullEntries = 0;
  }
  void produce (int element)
  {
    pthread_mutex_lock (&monitor);
    while (fullEntries == MAX)
      pthread_cond_wait (&empty, &monitor);
    buffer[fill] = element;
    fill = (fill + 1) % MAX;
    fullEntries++;
    //sleep(rand()%2);
    pthread_cond_signal (&full);
    pthread_mutex_unlock (&monitor);
  }
  int consume ()
  {
    pthread_mutex_lock (&monitor);
    while (fullEntries == 0)
      pthread_cond_wait (&full, &monitor);
    int tmp = buffer[use];
    use = (use + 1) % MAX;
    fullEntries--;
    //sleep(rand()%2);
    pthread_cond_signal (&empty);
    pthread_mutex_unlock (&monitor);
    return tmp;
  }
}b;
void* producer(void *arg){
int i=1;
while(true){
b.produce(i);
i++;
}
}
void* consumer(void *arg){
while(true){
cout<<b.consume()<<" ";
}
}
int main(){
pthread_t t1,t2;
pthread_create(&t1,NULL,producer,NULL);
pthread_create(&t2,NULL,consumer,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}

每当在 BoundedBuffer.consume() 和 BoundedBuffer.produce(int) 中添加 sleep() 时,它都不会打印任何输出。但是当这些函数中没有 sleep() 时,它可以正常工作并将输出打印为应该是。为什么会这样?
参考: http://pages.cs.wisc.edu/~remzi/OSTEP/threads-monitors.pdf

【问题讨论】:

  • 顺便说一句,通常最好将信号放在临界区之外。
  • @kec - 这不是真的。请参阅stackoverflow.com/questions/4544234/… 了解原因
  • @Sean:关于该问题的选定答案具有误导性。给出的初始案例根本没有锁定,这不是我的建议。至于哪个更好,我认为在非实时应用程序中,在关键部分之外仍然更好。有关详细信息,请参阅该问题的第二个答案和引用的 Google 群组帖子。

标签: c++ multithreading operating-system synchronization ipc


【解决方案1】:

当我使用 fflush(stdout) 时,我看到输出正在打印

while(true){
cout<<"["<<b.consume()<<"] ";
fflush(stdout)
}

输出:

Magnum@SimpleGuy:~ [52]$ ./a.out [1] [2] [3] [4] [5] [6] [7] [8]

【讨论】:

  • 这就是std::flush io-manipulator 的用途。
  • @sonu kumar:如果以上解决了你的问题,你可以采纳答案,让其他人也能受益!
  • cout
  • @SimpleGuy 我过去从未遇到过此类问题。你知道为什么会这样吗?
  • @sonu kumar : fflush 在您的情况下用于刷新缓冲区(标准输出)。如果您过去没有遇到问题,那么您的缓冲区过去会自动刷新。很多时候它会自动刷新(比如可以根据缓冲区已满来推送标准)。因此,在过去的情况下会遇到
【解决方案2】:

您尝试运行该程序多长时间?
您是否阅读了有关 rand 和 sleep 的文档。
Rand function Link

Sleep function link

可能会发生 rand 每次都返回一个很大的数字,而您的生产者在第一次生产某些东西后会休眠很长时间,而在此期间您的消费者只是等待 cond_wait。

尝试使用较小的睡眠间隔“usleep”或类似的东西,您会发现您的程序运行良好。

milli/micro second sleep function link

【讨论】:

  • 我没有投反对票,但你的声明 It could be happening that rand returns a big number every time 不可能是真的,因为它是 rand()%2 所以 sleep 不能超过 0 or 1
  • 不是我,可能是因为注释掉的行中有%2
  • 我的错!我错过了。感谢您的评论。我确实运行了它,将 endl 放在语句的末尾,它运行良好。
  • @Rush 当我运行这个程序时,打印输出所需的时间比它应该花费的时间要长。无论如何我没有投票。添加 fflush 后,工作正常。
猜你喜欢
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-25
  • 2013-11-10
  • 1970-01-01
相关资源
最近更新 更多