长时间锁定互斥锁安全吗?
Is locking a mutex for a long time safe?
存在一系列问题,其中互斥体本身(没有条件变量等额外内容)可用于同步线程。
例如,假设我希望后台线程执行一些可能耗时的初始化,然后执行其主要工作,但主要工作不应早于我从主线程发出信号之前开始:
std::thread backgroundThread ([]() {
initialize ();
waitForSignalQ ();
doMainJob ();
});
…;
emitSignalQ ();
是的,我知道我可以使用互斥量+布尔变量+条件变量来实现waitForSignalQ
和emitSignalQ
。或者,我可以使用 void-returning future + void-returning promice 来达到同样的目的,正如 Scott Meyers 所建议的那样。
但这里更简单的方法似乎是只使用一个互斥量:
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();
但是这种方法有效吗?还是有一些缺点(例如:OS级互斥锁时间限制,软件分析工具的误报等)?
P。 S.:
• 是的,我知道如果 myMutex
未解锁(由于 backgroundThreadCantStartItsMainJob.unlock()
之前的异常等),问题将会出现,但问题不在于此(使用 condvar 和未来的方法我们得到如果主线程 "forgets" 发出信号 Q).
同样的问题
• 是的,我知道在实践中可能有多种信号 Q 变体(如 "proceed to the main job" 与 "cancel"),问题不在于此(以及 condvar 和未来方法) ,所讨论的方法也允许传递额外的数据)。
长时间锁定互斥锁没有什么特别的缺点。
如果我没理解错的话,您有一个线程会在其初始化期间锁定互斥量。另一个线程将尝试获取该互斥量(以确保另一个线程的初始化已完成),然后为程序运行时的其余部分获取互斥量。
很好。拥有互斥量没有运行时成本。 OS 不会超时或任何事情。挑战是软件工程方面的挑战:让必须维护它的人清楚、可读和理解。除此之外,架构真的取决于你。
存在一系列问题,其中互斥体本身(没有条件变量等额外内容)可用于同步线程。
例如,假设我希望后台线程执行一些可能耗时的初始化,然后执行其主要工作,但主要工作不应早于我从主线程发出信号之前开始:
std::thread backgroundThread ([]() {
initialize ();
waitForSignalQ ();
doMainJob ();
});
…;
emitSignalQ ();
是的,我知道我可以使用互斥量+布尔变量+条件变量来实现waitForSignalQ
和emitSignalQ
。或者,我可以使用 void-returning future + void-returning promice 来达到同样的目的,正如 Scott Meyers 所建议的那样。
但这里更简单的方法似乎是只使用一个互斥量:
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();
但是这种方法有效吗?还是有一些缺点(例如:OS级互斥锁时间限制,软件分析工具的误报等)?
P。 S.:
• 是的,我知道如果 myMutex
未解锁(由于 backgroundThreadCantStartItsMainJob.unlock()
之前的异常等),问题将会出现,但问题不在于此(使用 condvar 和未来的方法我们得到如果主线程 "forgets" 发出信号 Q).
同样的问题
• 是的,我知道在实践中可能有多种信号 Q 变体(如 "proceed to the main job" 与 "cancel"),问题不在于此(以及 condvar 和未来方法) ,所讨论的方法也允许传递额外的数据)。
长时间锁定互斥锁没有什么特别的缺点。
如果我没理解错的话,您有一个线程会在其初始化期间锁定互斥量。另一个线程将尝试获取该互斥量(以确保另一个线程的初始化已完成),然后为程序运行时的其余部分获取互斥量。
很好。拥有互斥量没有运行时成本。 OS 不会超时或任何事情。挑战是软件工程方面的挑战:让必须维护它的人清楚、可读和理解。除此之外,架构真的取决于你。