c++ - 使用升压锁进行 RAII 对信号量的访问

标签 c++ semaphore boost-thread

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

我的猜测是使用信号量作为 Lockable 的模型应该没问题。我浏览了一些增强源,它“似乎”没问题。这些锁似乎没有存储对 this_thread 或类似内容的显式引用。此外,Lockable 概念没有像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) 我希望任务的第二个、更耗时的部分由另一个线程完成,可能是从等待完成由主线程启动的任务的从属线程池中选择的。

注意:我最近在这里发布了同样的问题(有点)Modelling boost::Lockable with semaphore rather than mutex (previously titled: Unlocking a mutex from a different thread) 但我混淆了互斥锁和信号量,所以关于使用升压锁的问题并没有真正得到解决。

最佳答案

@dan,我觉得你把事情搞得太复杂了。您所描述的内容可以通过主处理线程、同步队列和工作线程[池]轻松实现。您似乎也落入了使用锁来“保护代码”的常见陷阱,而这是您需要保护的数据结构。

定义您的共享数据,在数据可能不一致时识别最小关键部分。用锁支撑那个

关于c++ - 使用升压锁进行 RAII 对信号量的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2755720/

相关文章:

c++ - boost::thread 在每次运行时产生不同的结果

c++ - 如何处理和包含用于在不同计算机上构建 Visual Studio 2010 解决方案的 header 和库

c++ - COM 接口(interface)方法限制

java - 简单的 Java 代码允许单线程访问和其他线程跳过/继续

c# - SemaphoreSlim 在极端条件下无法工作?

multithreading - 为什么Intel TBB不提供boost之类的条件变量?

c++ - 互斥实现可以互换吗(独立于线程实现)

c++ - 使用指针访问struct c++ vector 中的元素

java - android studio 使用JNI 构建c/c++,但c/c++ 需要另一个lib.a,如何解决

php - 一段时间后信号量键丢失