2010-10-20 64 views
2

我有一个使用线程池实现的基于UDP的应用程序。线程池共享资源锁定问题

的消息推到一个队列,当有事情要做或队列中的消息线程池被唤醒。线程池处理每个消息并将它们传递给保持某种状态的会话对象。即UDP分组是会话的一部分,并且会话正在重新组装大块数据。

该会话对象需要访问共享资源。但是,另一个会话对象也可以从资源中读取,但不能在写入时读取。

现在的问题是,对话对象DoWork的方法可以从不同的线程调用,我需要防止任何人写的。所以要做到这一点,我需要锁定资源。

这是问题出现的地方。如果我使用标准的互斥锁,它不能在线程间移植,所以我会尝试访问资源,并且应该能够将数据放入资源中,但除非我是锁定资源的原始线程,否则我不能这样做。

它是想我需要一个会话密钥来访问的资源,而不是我的 线程ID。

我该如何解决这个问题?在这里提升shared_mutex似乎有点受限。

回答

0

我正在做的是使资源成为一个对象。 框架版本看起来 这样的:

例如

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也是。完成后可以调用解锁。不同的线程可以解锁,而不是锁定它的线程。

另外,在写入时会防止读取,直到调用解锁为止。

0

听起来像是你想有一个reader/writer lock

+0

好的,我知道我需要一个读写器锁,但是我不知道的和刚刚通过实验发现的是另一个线程可以解锁资源。 – Matt 2010-10-20 02:49:30

0

据我了解oyu需要多个读者和一个作家模型。如果是这样,你可以在“getter”中创建boost :: shared_lock,在“setter”中创建boost :: unique_lock(这两个都是针对“lock_”创建的)。

回复你的方法“打开”:“读”是一个本地对象,因此在完成“打开”将被删除。什么意思,当你离开“打开”时,lock_将被解锁(shared_lock的析构函数这么做)。