【发布时间】:2011-04-08 08:38:50
【问题描述】:
我有一个名为“subscribedQueue”的类。此类通过其订阅的发布者(复数)调用其推送方法接收其数据。
在另一个线程中,调用此类的 pop 方法来接收该数据。 因此在某种意义上,这个类是多个发布者和他们的订阅者之间的一种缓冲。对于实现,我基于找到的有关线程安全队列here 的信息。
现在我的问题是双重的:
- 如果我将使用相同的互斥锁来推送和弹出值(目前我正在使用两个不同的互斥锁),我的程序是否可能会卡住,等待被阻止的推送?
- 如果没有,push 和 pop 方法怎么可能通过'lock(the_same_mutex)'。
我的假设是,如果我将使用相同的互斥体并且程序进入 pop 方法,它将在 pop 中获取锁,检查队列是否为空并等待条件变量中永远无法设置push 方法(因为锁已经被 pop 获取)。
当前代码(使用两个不同的互斥锁):
#include <boost/thread.hpp>
#include <queue>
#include "subscriber.h"
#include "pubdata.h"
#ifdef DEBUG
#include <iostream>
#include <boost/lexical_cast.hpp>
#endif
namespace PUBLISHSUBSCRIBE
{
template<class T>
class SubscribedQueue: public PUBLISHSUBSCRIBE::Subscriber<T>, private std::queue< PubData<T> >
{
public:
PubData<T> pop(); //removes the next item from the queue, blocks until the queue is not empty
void push(const PubData<T> data); //method used by the publisher to push data onto the queue
private:
mutable boost::mutex writeMutex_; //only needed for publishing/pushing data
mutable boost::mutex readMutex_; //only needed for reading/popping data
boost::condition_variable notify_;
};
template<class T>
PubData<T> SubscribedQueue<T>::pop() { //Blocks until the queue is not empty
boost::mutex::scoped_lock lock(readMutex_);
while(std::queue< PubData<T> >::empty())
notify_.wait(lock); //block until recieving a notification AND the queue is not empty
PubData<T> head = std::queue< PubData<T> >::front();
std::queue< PubData<T> >::pop();
#ifdef DEBUG
std::string debugOut("pop: " + boost::lexical_cast<std::string>(head) + " - timestamp: " + boost::lexical_cast<std::string>(head.timestamp()) + " - from: " + boost::lexical_cast<std::string>(this) + "\n" );
std::cout <<debugOut;
#endif
lock.unlock();
return head;
}
template<class T>
void SubscribedQueue<T>::push(const PubData<T> data){
boost::mutex::scoped_lock lock(writeMutex_);
#ifdef DEBUG
std::cout << "published: " << data << std::endl;
#endif
std::queue< PubData<T> >::push(data);
lock.unlock();
notify_.notify_one();
}
}
#endif //SUBSCRIBEDQUEUE_H
[edit] 最让我担心的是:我有一个 boost::condition_variable notify_ 在 pop 中执行“等待直到通知”。 但是 pop 必须首先锁定互斥锁,同样的互斥锁也必须在“推送”中锁定以“通知”条件变量。
所以不会导致死锁,为什么不呢?
【问题讨论】:
标签: c++ multithreading mutex boost-thread