我有一个基于UDP的应用程序,它是使用线程池实现的。
消息被推送到队列中,当有事情或队列中的消息时,线程池被唤醒。线程池处理每个消息并将其移交给 持有某种状态的会话对象。即UDP数据包是会话的一部分,会话正在重组大数据块。
该会话对象需要访问共享资源。但是,另一个会话对象也可以从资源中读取,但不会在写入时读取。
现在的问题是会话对象可以从不同的线程调用DoWork方法,我需要阻止任何人写入它。所以要做到这一点,我需要锁定资源。
这是问题出现的地方。如果我使用标准互斥锁,它在线程之间不可移植,所以我将尝试访问资源,并且应该能够将数据放入资源,但我不能,除非我是锁定资源的原始线程。
我认为我需要一个会话密钥来访问资源而不是我的资源 线程ID。
我如何解决这个问题?在这种情况下,提升shared_mutex似乎有点受限。
答案 0 :(得分:0)
听起来像是想要reader/writer lock。
答案 1 :(得分:0)
我正在做的是使资源成为一个对象。 骨架版本看起来 像这样:
e.g。
class Resource
{
public:
enum {READ, WRITE};
void Open(int mode=READ)
{
if (mode == WRITE){
Lock();
// Access resource
} else if (mode == READ){
// Try to get read access (scoped version)
boost::shared_lock<boost::shared_mutex> read(lock_, boost::try_to_lock);
if (!read){
// throw exception
}
// Read access to resource
}
}
Lock()
{
lock_.lock_upgrade();
lock_.unlock_upgrade_and_lock();
}
Unlock()
{
lock_.unlock();
}
private:
boost::shared_mutex lock_;
}
现在我可以有多个读者。当我想写资源时(在任何时候)我可以调用Lock()。 Open也是如此。完成后可以调用解锁。一个不同的线程可以解锁而不是锁定它的那个。
此外,写入时会阻止读取,直到调用解锁。
答案 2 :(得分:0)
据我所知,oyu需要多个读者和一个作家模型。如果是这样,你可以在“getter”中创建boost :: shared_lock,在“setter”中创建boost :: unique_lock(两者都是针对“lock _”创建的。)
重做方法“打开”:“读取”是一个本地对象,因此当“打开”完成时它将被删除。什么意思是当你离开“打开”时,lock_将被解锁(shared_lock的析构函数执行此操作)。