简体   繁体   English

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

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

Suppose I write a C++ semaphore class with an interface that models the boost Lockable concept (ie lock(); unlock(); try_lock(); etc.). 假设我编写了一个C ++信号量类,该类具有模拟boost Lockable概念的接口(即lock(); unlock(); try_lock();等)。 Is it safe/recommended to use boost locks for RAII access to such an object? 使用boost锁进行RAII访问此类对象是否安全/建议? In other words, do boost locks (and/or other related parts of the boost thread library) assume that the Lockable concept will only be modeled by mutex-like objects which are locked and unlocked from the same thread? 换句话说,boost锁(和/或boost线程库的其他相关部分)是否假定Lockable概念仅由从同一线程锁定和解锁的互斥锁类对象建模?

My guess is that it should be OK to use a semaphore as a model for Lockable. 我的猜测是可以使用信号量作为Lockable的模型。 I've browsed through some of the boost source and it "seems" OK. 我已经浏览了一些boost源,并且看起来“不错”。 The locks don't appear to store explicit references to this_thread or anything like that. 锁似乎没有存储对this_thread或类似内容的显式引用。 Moreover, the Lockable concept doesn't have any function like whichThreadOwnsMe() . 而且, whichThreadOwnsMe()概念没有诸如whichThreadOwnsMe()类的任何功能。 It also looks like I should even be able to pass a boost::unique_lock<MySemaphore> reference to boost::condition_variable_any::wait . 看起来我什至应该甚至可以传递boost::unique_lock<MySemaphore>引用到boost::condition_variable_any::wait However, the documentation is not explicitly clear about the requirements. 但是,文档中并未明确要求。

To illustrate what I mean, consider a bare-bones binary semaphore class along these lines: 为了说明我的意思,请考虑以下几行的准二进制信号量类:

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.
}

Now suppose that somewhere, either on an object or globally, I have 现在假设某个地方,无论是在对象上还是全局上

MySemaphore sem;

I want to lock and unlock it using RAII. 我想使用RAII对其进行锁定和解锁。 Also I want to be able to "pass" ownership of the lock from one thread to another. 我也希望能够将锁的所有权从一个线程“传递”到另一个线程。 For example, in one thread I execute 例如,在一个线程中我执行

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

While another thread is executing something like 当另一个线程正在执行类似

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

The reason I am doing this is that I don't want anyone else to be able to get the lock on sem in between the time that the first thread executes doSomeWorkWithSharedObject() and the time the second executes doMoreWorkWithSameSharedObject() . 我这样做的原因是,我不希望别人能得到上了锁sem的时间之间的第一线程执行doSomeWorkWithSharedObject()和时间第二执行doMoreWorkWithSameSharedObject() Basically, I'm splitting one task into two parts. 基本上,我将一项任务分为两部分。 And the reason I'm splitting the task up is because (1) I want the first part of the task to get started as soon as possible, (2) I want to guarantee that the first part is complete before doTask() returns, and (3) I want the second, more time-consuming part of the task to be completed by another thread, possibly chosen from a pool of slave threads that are waiting around to finish tasks that have been started by master threads. 我之所以将任务拆分的原因是:(1)我希望任务的第一部分尽快开始,(2)我想保证在doTask()返回之前第一部分是完整的, (3)我希望任务的第二个更耗时的部分由另一个线程来完成,这可能是从一个等待完成由主线程启动的任务的从属线程池中选择的。

NOTE: I recently posted this same question (sort of) here Modelling boost::Lockable with semaphore rather than mutex (previously titled: Unlocking a mutex from a different thread) but I confused mutexes with semaphores, and so the question about using boost locks didn't really get addressed. 注意:我最近在这里发布了相同的问题(某种),在使用信号量而不是互斥锁对boost :: Lockable进行建模(以前的标题:从另一个线程解锁互斥锁),但是我将互斥锁与信号量混淆了,所以有关使用boost锁的问题并没有真正得到解决。

@dan, I think you are overcomplicating things. @dan,我想您太过复杂了。 What you are describing is easily achievable with a main processing thread, a synchronized queue, and a [pool of] worker thread(s). 您所描述的内容可以通过一个主处理线程,一个同步队列和一个[工作线程池]轻松实现。 It also looks like you are falling into a common trap of using locks to "protect code", while it's the data structures you need to protect. 看起来您已经陷入使用锁“保护代码”的常见陷阱,而这正是您需要保护的数据结构。

Define your shared data, identify minimal critical sections when the data might be inconsistent. 定义您的共享数据,并在数据可能不一致时确定最少的关键部分。 Brace that with locks. 打起精神与锁。

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

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