代码之家  ›  专栏  ›  技术社区  ›  hookenz

线程池共享资源锁定问题

  •  2
  • hookenz  · 技术社区  · 14 年前

    我有一个使用线程池实现的基于UDP的应用程序。

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

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

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

    这就是问题所在。如果我使用一个标准的互斥体,它在线程之间是不可移植的,因此我将尝试访问资源,并且应该能够将数据放入资源中,但是除非我是锁定资源的原始线程,否则我不能。

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

    我该怎么解决这个问题?在这种情况下,boost shared\u mutex似乎有点有限。

    3 回复  |  直到 14 年前
        1
  •  0
  •   Community paulsm4    7 年前

    听起来你想要一个 reader/writer lock .

        2
  •  0
  •   hookenz    14 年前

    我要做的是把资源变成一个对象。 骨架版本的外观 这样地:

    例如

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

    此外,在调用unlock之前,在写入时会阻止读取。

        3
  •  0
  •   Gregory    14 年前

    据我所知,奥尤需要多个读者和一个作家模型。如果是这样,您可以在“getter”中创建boost::shared_锁,在“setter”中创建boost::unique_锁(这两个锁都是针对“lock_u”创建的)。

    您的方法“open”:“read”是一个本地对象,因此当“open”完成时,它将被删除。什么意思是当你离开“open”(共享锁的析构函数这样做)时锁将被解锁。