C++ 我定义的互斥类中的逻辑错误以及我在生产者-消费者程序中使用它的方式-pthreads
我已经添加了一个互斥类来支持RAII。我不确定我使用它的方式是否正确 生产者锁定队列后,程序意外完成 MutexClass.hC++ 我定义的互斥类中的逻辑错误以及我在生产者-消费者程序中使用它的方式-pthreads,c++,pthreads,producer-consumer,C++,Pthreads,Producer Consumer,我已经添加了一个互斥类来支持RAII。我不确定我使用它的方式是否正确 生产者锁定队列后,程序意外完成 MutexClass.h #ifndef MUTEXCLASS #define MUTEXCLASS #include <pthread.h> class MutexClass { private: pthread_mutex_t & _mutexVariable; public: MutexClass (pthread_mutex_t &);
#ifndef MUTEXCLASS
#define MUTEXCLASS
#include <pthread.h>
class MutexClass
{
private:
pthread_mutex_t & _mutexVariable;
public:
MutexClass (pthread_mutex_t &);
~MutexClass ();
};
#endif // MUTEXCLASS
另外,请注意输出的以下部分:
队列2,被消费者锁定:140388157085440
由使用者移除:1403881654781441,由使用者锁定:140388148692736
我只创建了2个消费者,但这里显示的PID是3个。为什么会这样?当前,每次创建新的
互斥类时,都要将互斥变量
初始化为PTHREAD\u MUTEX\u初始值设定项
。考虑如果线程A持有<代码> MutExchange变量< /C>,线程B想要获取互斥体:会发生什么?
thread A tries to lock mutexVariable and succeeds
mutexVariable = PTHRAED_MUTEX_INITIALIZER
pthread_mutex_lock(mutexVariable)
thread B tries to lock mutexVariable and succeeds
// this assignment overwrites the locked state thread A has stored
mutexVariable = PTHRAED_MUTEX_INITIALIZER
// mutex is default-initialized (not locked) - so lock it
pthread_mutex_lock(mutexVariable)
// both threads now believe they have the mutex
// and all syncronization is lost
thread B unlocks mutexVariable
// succeeds
thread A unlocks mutexVariable
// uh.. it is not even locked any more?!
只能在main.cpp:13
中初始化一次mutexVariable
:
pthread_mutex_t mutexVariable = PTHRAED_MUTEX_INITIALIZER;
并从MutexClass
中删除初始化
不确定这是否会修复所有的问题,但这是我首先要做的事情。
这个代码有一些问题,但我想知道:为什么你不使用C++代码线程库中的<代码> STD::互斥体< /C>和<代码> STD::他们会为您处理pthread交互的所有细节。@ChristianAichinger我写这篇文章是为了学习。我现在不需要任何库函数来帮助。当我知道我在做什么时,我会使用它们。“Qt的类是为同名者而来的,因为我是Qt创建者。请忽略它们。”不。您应该首先提取一个最小的示例。这就是说,传递互斥类引用(!)的方式显然是自找麻烦,它无法进行任何封装。还请学习所谓的“三定律”和一些现有的线程库,如Boost或您的C++11编译器。顺便说一句:查看friend
关键字。它允许您紧密地封装互斥和事件,并且只在单个等待函数中提供对其内部的访问。@UlrichEckhardt您应该首先提取一个最小的示例。
您的意思是我应该用emacs编写程序?Qt的课程在这里有什么不同你传递互斥类引用(!)的方式显然是自找麻烦,
我要求你在没有Boost库的情况下(目前)写一个解释问题及其解决方案的答案。我不在乎你如何编辑你的代码,但是堆栈溢出准则要求您提取一个最小的示例,每个人都可以使用它来重现您的问题。此外,多余的代码会分散读者(和作者)对实际问题的注意力。因此,剥离Qt Creator插入的任何不必要的东西是你的工作。谢谢,好吧,至少这个问题已经解决了。您还谈到了哪些其他问题?例如,构造函数不明确,加上Ulrich Eckhardt提到的内容。一般来说,直接使用pthread不会给您带来启示。使用std::mutex和friends,但要了解封面下发生的事情。“隐藏”并不是指pthread级别,而是指CPU/内存级别。pthread库是一个不幸的实现细节。感谢您的后续操作。顺便说一句,我不太明白为什么人们反对pthread。如果我使用了一些高级库,它会自动处理所有的细节,我怎么知道您的解决方案呢?为什么不需要学习呢?要成为一名农民,你必须了解耕作。为什么耕地,何时耕地,以及如何耕地。但今天,你不应该花时间学习如何让牛拉你的木犁。我们不再使用牛和木犁,我们有带金属犁的拖拉机您在这个问题中了解到的是pthreads的细节,std::mutex甚至不会让您犯这个错误!您最终仍需要更深入的理解,但这取决于CPU/内存/缓存/重新排序,而不是pthreads。您也不同意乌尔里希指出的三分之一规则值得学习吗?你认为我会从boost library中学到这个规则吗?我不想在这里争论。我只是想学编程!
...
...
Queue 140388157085440
Removed by Consumer: 1403881570854401403881654781442
Queue , Locked by Consumer: 1140388148692736
Removed by Consumer: , Length of queue 1 is: , First check by Producer: 140388148692736, Length of queue 2 is: 1403881654781449
Queue
Queue 2, UnLocked by Consumer: 140388148692736
Consumer: 9
Queue 1, UnLocked by Consumer: 140388157085440
Queue 2, First check by Consumer: 1403881570854401140388148692736
Queue 1, First check by Consumer: 140388148692736
Queue , Locked by Producer:
Queue 2, Locked by Consumer: 140388157085440
Removed by Consumer: 1403881654781441, Locked by Consumer: 140388148692736
Pushed by Producer 140388165478144: Length of queue 1 is: 10
Queue 1, UnLocked by Producer: 140388165478144
Queue 2, First check by Producer: 140388165478144
Queue 2, Locked by Producer: 140388165478144The program has unexpectedly finished.
thread A tries to lock mutexVariable and succeeds
mutexVariable = PTHRAED_MUTEX_INITIALIZER
pthread_mutex_lock(mutexVariable)
thread B tries to lock mutexVariable and succeeds
// this assignment overwrites the locked state thread A has stored
mutexVariable = PTHRAED_MUTEX_INITIALIZER
// mutex is default-initialized (not locked) - so lock it
pthread_mutex_lock(mutexVariable)
// both threads now believe they have the mutex
// and all syncronization is lost
thread B unlocks mutexVariable
// succeeds
thread A unlocks mutexVariable
// uh.. it is not even locked any more?!
pthread_mutex_t mutexVariable = PTHRAED_MUTEX_INITIALIZER;