C++ 我定义的互斥类中的逻辑错误以及我在生产者-消费者程序中使用它的方式-pthreads

C++ 我定义的互斥类中的逻辑错误以及我在生产者-消费者程序中使用它的方式-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 &);

我已经添加了一个互斥类来支持RAII。我不确定我使用它的方式是否正确

生产者锁定队列后,程序意外完成

MutexClass.h

#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;