繁体   English   中英

使用增强锁使RAII访问信号量

[英]Using boost locks for RAII access to a semaphore

假设我编写了一个C ++信号量类,该类具有模拟boost Lockable概念的接口(即lock(); unlock(); try_lock();等)。 使用boost锁进行RAII访问此类对象是否安全/建议? 换句话说,boost锁(和/或boost线程库的其他相关部分)是否假定Lockable概念仅由从同一线程锁定和解锁的互斥锁类对象建模?

我的猜测是可以使用信号量作为Lockable的模型。 我已经浏览了一些boost源,并且看起来“不错”。 锁似乎没有存储对this_thread或类似内容的显式引用。 而且, whichThreadOwnsMe()概念没有诸如whichThreadOwnsMe()类的任何功能。 看起来我什至应该甚至可以传递boost::unique_lock<MySemaphore>引用到boost::condition_variable_any::wait 但是,文档中并未明确要求。

为了说明我的意思,请考虑以下几行的准二进制信号量类:

class MySemaphore{
  bool locked;
  boost::mutex mx;
  boost::condition_variable cv;
public:
  void lock(){
    boost::unique_lock<boost::mutex> lck(mx);
    while(locked) cv.wait(lck);
    locked=true;
  }

  void unlock(){
    {
      boost::lock_guard<boost::mutex> lck(mx);
      if(!locked) error();
      locked=false;
    }
    cv.notify_one();
  }
// bool try_lock(); void error(); etc.
}

现在假设某个地方,无论是在对象上还是全局上

MySemaphore sem;

我想使用RAII对其进行锁定和解锁。 我也希望能够将锁的所有权从一个线程“传递”到另一个线程。 例如,在一个线程中我执行

void doTask()
{
  boost::unique_lock<MySemaphore> lock(sem);
  doSomeWorkWithSharedObject();
  signalToSecondThread();
  waitForSignalAck();
  lock.release();
}

当另一个线程正在执行类似

{
waitForSignalFromFirstThread();
ackSignal();
boost::unique_lock<MySemaphore>(sem,boost::adopt_lock_t());
doMoreWorkWithSameSharedObject();
}

我这样做的原因是,我不希望别人能得到上了锁sem的时间之间的第一线程执行doSomeWorkWithSharedObject()和时间第二执行doMoreWorkWithSameSharedObject() 基本上,我将一项任务分为两部分。 我之所以将任务拆分的原因是:(1)我希望任务的第一部分尽快开始,(2)我想保证在doTask()返回之前第一部分是完整的, (3)我希望任务的第二个更耗时的部分由另一个线程来完成,这可能是从一个等待完成由主线程启动的任务的从属线程池中选择的。

注意:我最近在这里发布了相同的问题(某种),在使用信号量而不是互斥锁对boost :: Lockable进行建模(以前的标题:从另一个线程解锁互斥锁),但是我将互斥锁与信号量混淆了,所以有关使用boost锁的问题并没有真正得到解决。

@dan,我想您太过复杂了。 您所描述的内容可以通过一个主处理线程,一个同步队列和一个[工作线程池]轻松实现。 看起来您已经陷入使用锁“保护代码”的常见陷阱,而这正是您需要保护的数据结构。

定义您的共享数据,并在数据可能不一致时确定最少的关键部分。 打起精神与锁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM