c++ - 只锁定两个可能的互斥量之一

标签 c++ multithreading mutex

我有一个模拟汽车车间的多线程 C++ 程序。基本上,car 在这里是一个线程,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;
}

所以我想锁定 r_mutexl_mutex,所以有 4 种可能的情况:

  • 两个都没有锁,我锁哪个
  • 右边的锁了,我锁左边的
  • 左边的锁了,我锁右边的
  • 他们都被锁定了,我等

这里的问题是:在 C++ 中是否有一种机制可以只锁定一个给定的互斥量? (就像我给一些功能我的 r_mutex 和 l_mutex 并且它选择未锁定的一个并为我锁定它)。

最佳答案

互斥体在这里不是正确的同步原语。这可以通过信号量(基本上是互斥量为 0-1 的 0-n 基元)来完成,但标准库中没有信号量。

但是,您可以在此处使用一个条件变量。您将需要:

  • 一个条件变量来表示“站点中有空闲空间”
  • 代表车站可用空间的计数器(或其他方式,例如两个 bool 值)
  • 保护这些的互斥体

进站时,锁定互斥锁,看看是否有空闲空间。如果有,占用一个,释放互斥量,并得到修复。如果两者都已满,则等待条件变量(这将释放互斥量)。

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

在代码中:

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();
    }
}

关于c++ - 只锁定两个可能的互斥量之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50714317/

相关文章:

c++ - 为什么我在静态库中缺少显式模板特化的符号?

Java 服务器 - 多个客户端处理 - 使用线程是最佳选择吗?

c# - 使用多线程与 C# 进行 OCR

c++ - MFC:创建无模式对话框而不显示

c++ - C 结构中的内存对齐

java - 抛出 InterruptedException 时不会清除线程中断状态

c++ - 当互斥锁解锁时,它是notify_all还是notify_one?

c# - C# 中的命名锁集合?

go - 如何在 Golang 中对多个变量应用单独的 Mutex?

c++ - 使用多个 gSOAP 实现时的重新定义错误