标准库提供mutex
类,可以手动锁定和解锁它:
std::mutex m;
m.lock();
// ...
m.unlock();
然而,该库显然也认识到一个常见的情况是在某个时刻锁定互斥锁,并在离开块时将其解锁。为此,它提供了std::lock_guard
和std::unique_lock
:
std::mutex m;
std::lock_guard<std::mutex> lock(m);
// ...
// Automatic unlock
我认为线程的一个相当常见的模式是创建一个(作为堆栈变量或成员),然后join
it before destructing it:
std::thread t(foo);
// ...
t.join();
编写一个thread_guard
似乎很容易,它会占用thread
(或thread
s的序列),并且会自行调用join
:
std::thread t(foo);
thread_guard<std::thread> g(t);
// ...
// Join automatically
是否有类似的标准库类?
如果没有,是否有理由避免这种情况?
答案 0 :(得分:4)
Scott Meyer的书“Modern Effective c ++”
中讨论了这个问题问题在于,如果存在其他默认行为(分离或连接),则会在您忘记存在隐式操作时导致难以发现错误。因此,如果未明确加入或分离,则破坏时的实际默认行为是断言。由于这个原因,也没有“警卫”课程。
如果总是想要加入,那么自己编写这样的课程是安全的。但是当有人使用它并希望分离时,人们会忘记析构函数会隐式加入它。这就是写这种功能的风险。
作为替代方案,您可以使用scope_guard
通过boost或愚蠢的库(我个人更喜欢)并在开头明确声明您的意图并将执行。或者,您可以编写基于策略的“Guard”类,您必须明确说明要对销毁执行的操作。