提问者:小点点

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


有一组问题可以使用互斥体本身(不需要附加的东西,如条件变量)来同步线程。

例如,假设我希望一个后台线程执行一些可能很耗时的初始化,然后执行它的主作业,但是主作业不应在我从主线程给出信号之前开始:

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

…;

emitSignalQ ();

是的,我知道我可以使用互斥量+布尔变量+条件变量来实现WaitForSignalQEmitSignalQ。 或者,我可以使用void-returning future+void-returning promaces来达到同样的目的,就像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和future方法,如果主线程“忘记”发出信号Q,我们会遇到同样的问题)。
•是的,我知道在实践中,使用信号Q的几种变体(例如“继续到主作业”与“取消”)可能是有意义的,但问题不在于此(以及condvar和future方法,所讨论的方法也允许传递额外的数据)。


共1个答案

匿名用户

长时间锁定互斥锁并没有什么特别的缺点。

如果我没有理解错的话,您有一个线程,它将在互斥体的初始化过程中锁定互斥体。 另一个线程将尝试获取该互斥体(确保另一个线程的init已完成),然后在程序运行时的其余部分获取该互斥体。

那很好。 使用互斥体没有运行时成本。 操作系统不会超时或其他任何事情。 这是一个软件工程的挑战:使它清晰,可读和可理解的人将不得不维护它。 除此之外,体系结构真的取决于你。