存在一系列问题,其中互斥体自身(没有条件变量之类的其他东西)可用于同步线程。
例如,假设我希望后台线程执行一些可能耗时的初始化,然后执行其主任务,但是主任务的开始时间不应早于我从主线程发出信号的时间:
std::thread backgroundThread ([]() {
initialize ();
waitForSignalQ ();
doMainJob ();
});
…;
emitSignalQ ();
是的,我知道我可以使用互斥体+ bool 变量+条件变量来实现
waitForSignalQ
和emitSignalQ
。或者,正如斯科特·迈耶斯(Scott Meyers)所建议的,我可以出于相同的目的使用返回虚空的 future +返回虚空的 promise 。但是这里更简单的方法似乎只使用了一个互斥锁:
std::mutex myMutex;
std::unique_lock <std::mutex> backgroundThreadCantStartItsMainJob (myMutex);
std::thread backgroundThread ([&myMutex]() {
initialize ();
// This line won't return until myMutex is unlocked:
std::lock_quard <std::mutex> (myMutex);
doMainJob ();
});
…;
// This line will unlock myMutex:
backgroundThreadCantStartItsMainJob.unlock();
但是这种方法有效吗?还是存在一些缺点(例如:操作系统级互斥锁锁定时间限制,软件分析工具的误报等)?
P.S .:
•是的,我知道如果未解锁
myMutex
(由于backgroundThreadCantStartItsMainJob.unlock()
之前的异常等)会出现问题,但是问题不在于此(使用condvar和将来的方法,如果主线程“忘记”以发出信号Q)。•是的,我知道在实践中,有几种信号Q可能有意义(例如“进行主要工作”与“取消”),问题不在于此(以及condvar和将来的方法) ,所讨论的方法也允许传递额外的数据)。
最佳答案
长时间锁定互斥锁没有特定的缺点。
如果我理解正确,则您有一个线程将在互斥体初始化期间锁定该互斥体。另一个线程将尝试获取该互斥锁(以确保另一个线程的初始化已完成),然后在程序运行时的其余时间获取该互斥锁。
那样就好。拥有互斥量没有运行时成本。操作系统将不会超时或任何超时。挑战是软件工程:要使必须维护它的人员清楚,易读且易于理解。除此之外,该体系结构真的取决于您。
关于c++ - 长时间锁定互斥锁是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62305816/