我有一个模拟汽车研讨会的多线程C ++程序。基本上car
是一个线程,station
是一个资源。它的工作方式如下:汽车进入车间,它有一个车站列表(只是整数),它必须访问,以便修复。有三种类型的站:
最后两种类型对我来说很容易,因为在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 :(得分: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();
}
}
答案 1 :(得分:2)
在您的情况下,我会使用try_lock
方法。如果可以锁定,此方法返回true
(并锁定互斥锁),否则false
(已锁定互斥锁)。
if (!r_mutex.try_lock() && !l_mutex.try_lock())
std::cout << "All mutexes already locked" << std::endl;