仅锁定两个可能的互斥锁中的一个

min*_*234 5 c++ multithreading mutex

我有一个模拟汽车研讨会的多线程C++程序.基本上a car是这里的线程,a station是资源.它的工作方式如下:汽车进入车间,它有一个车站列表(只是整数),它必须访问,以便修复.有3种类型的站:

  • 1x2站 - 1站可同时修复2辆车
  • 1x1站 - 1站可同时修复1辆车
  • 2x1站 - 完成工作需要2个站点

最后两种类型对我来说很容易,因为1x1类型我只是锁定互斥锁station而其他线程必须等待.关于2x1类型我只是std::lock在两个站点去避免死锁等.

问题在于第一种类型.让我们想象一下,修理两辆车意味着一辆车在车站的左侧,另一辆在右侧(我将不得不画出这种情况ncurses).所以我考虑为这样的1x2类型实现一个站:

class station1x2 {
public:
    std::mutex r_mutex;
    std::mutex l_mutex;
}
Run Code Online (Sandbox Code Playgroud)

所以,我想无论是锁定的r_mutex还是l_mutex,所以有4种可能的情况:

  • 他们两个都没有锁定,我锁定其中任何一个
  • 右边一个被锁定,我锁定左边一个
  • 左边一个是锁定的,我锁定了一个
  • 他们两个都被锁定了,我等等

这里的问题是:C++中是否存在锁定给定互斥锁之一的机制?(就像我给了一些函数我的r_mutex和l_mutex它选择了未锁定的函数并为我锁定它).

Rei*_*ica 11

互斥锁不是正确的同步原语.这可以用信号量(基本上是0-n原语,其中互斥量为0-1)来完成,但标准库中没有信号量.

但是,您可以在此处使用条件变量.你会需要:

  • 一个条件变量,表示"站内有自由空间"
  • 一个计数器(或其他装置,如两个布尔),代表车站的自由空间
  • 保护这些的互斥锁

进入工作站时,锁定互斥锁并查看是否有可用空间.如果有,占用一个,释放互斥锁,并进行修复.如果两者都已满,请等待条件变量(这将释放互斥锁).

完成修复后,锁定互斥锁,将空间标记为空闲,释放互斥锁并通知条件变量(因为现在有空闲空间).

在代码中:

class station1x2 {
public:
    std::mutex mutex;
    std::condition_variable cond;
    int freeSpaces;

    void enter() {
      std::unique_lock<std::mutex> l(mutex);
      cond.wait(l, [&]() { return freeSpaces > 0; }
      --freeSpaces;
    }

    void exit() {
      {
        std::unique_lock<std::mutex> l(mutex);
        ++freeSpaces;
      }
      cond.notify_one();
    }
}
Run Code Online (Sandbox Code Playgroud)