长时间锁定互斥锁安全吗?

Is locking a mutex for a long time safe?

存在一系列问题,其中互斥体本身(没有条件变量等额外内容)可用于同步线程。

例如,假设我希望后台线程执行一些可能耗时的初始化,然后执行其主要工作,但主要工作不应早于我从主线程发出信号之前开始:

std::thread backgroundThread ([]() {
    initialize ();
    waitForSignalQ ();
    doMainJob ();
});

…;

emitSignalQ ();

是的,我知道我可以使用互斥量+布尔变量+条件变量来实现waitForSignalQemitSignalQ。或者,我可以使用 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 不会超时或任何事情。挑战是软件工程方面的挑战:让必须维护它的人清楚、可读和理解。除此之外,架构真的取决于你。