仅锁定两个可能的互斥锁之一
Lock only one of two possible mutexes
我有一个多线程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_mutex
或l_mutex
,所以有 4 种可能的情况:
- 他们两个都没有锁定,我锁定了他们中的任何一个
- 右边的锁定,我锁定左边 的
- 左边的被锁住,我锁右边的
- 他们两个都被锁住了,我等着
这里的问题是:C++是否有一种机制可以只锁定给定互斥锁中的一个?(就像我为我的r_mutex和l_mutex赋予某些功能,它选择未锁定的函数并为我锁定它(。
互斥锁在这里不是正确的同步原语。这可以通过信号量(基本上是 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();
}
}
在您的情况下,我会使用try_lock
方法。如果锁定可能,此方法返回true
(并锁定互斥锁(,否则false
返回(已锁定互斥锁(。
if (!r_mutex.try_lock() && !l_mutex.try_lock())
std::cout << "All mutexes already locked" << std::endl;
相关文章:
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 将fold表达式与std::一起用于两个元组
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- 仅锁定两个可能的互斥锁之一
- 同时锁定两个互斥对象
- 我们可以在不锁定两个或更多无锁容器的情况下原子地做一些事情吗?
- 响应性地检查两个队列而不锁定CPU
- 为什么pthread_mutex_t尝试锁定来自两个不同进程的共享内存时会出现段错误
- 如何锁定由属于两个不同类的两个线程修改的数据结构