gpt4 book ai didi

c++ - 在逗号运算符的 LHS 中初始化匿名互斥锁持有类实例

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:33:01 25 4
gpt4 key购买 nike

假设我有这样的代码:

#include "boost/thread/mutex.hpp"

using boost::mutex;
typedef mutex::scoped_lock lock;

mutex mut1, mut2;

void Func() {
// ...
}

void test_raiicomma_1() {
lock mut1_lock(mut1);
Func();
}

void test_raiicomma_2() {
(lock(mut1)), Func();
}

void test_raiicomma_3() {
(lock(mut1)), (lock(mut2)), Func(); // Warning!
}

int main()
{
test_raiicomma_1();
test_raiicomma_2();
test_raiicomma_3();
return 0;
}

如果函数 test_raiicomma_1() 被多个线程调用,它会锁定一个互斥量以防止任何其他线程同时调用 Func()。互斥锁在构造变量 mut1_lock 时被锁定,并在超出范围并被析构时释放。

这工作得很好,但就风格而言,需要为持有锁的临时对象命名让我很烦。函数 test_raiicomma_2() 试图通过初始化锁对象并在一个表达式中调用函数 Func() 来避免这种情况。

Func() 返回后,直到表达式结束才会调用临时对象析构函数是否正确? (如果是这样,您认为使用这个习惯用法是否值得,或者在单独的语句中声明锁是否总是更清楚?)

如果函数 test_raiicomma_3() 需要锁定两个互斥量,互斥量在调用 Func() 之前按顺序锁定,然后释放,是否正确,但不幸的是,可能会以任一顺序发布?

最佳答案

Is it correct that the temporary object destructor will not be called until the end of the expression, after Func() has returned?

保证构造函数和析构函数都被调用,因为它们有副作用,并且破坏只会发生在完整表达式的末尾。

我相信它应该有效

If the function test_raiicomma_3() needs to lock two mutexes, is it correct that the mutexes will be locked in order before calling Func(), and released afterwards, but may unfortunately be released in either order?

逗号总是从左到右求值,范围内的自动变量总是以创建的相反顺序销毁,所以我认为甚至可以保证它们也以(正确的)顺序释放

正如 litb 在评论中指出的那样,您需要大括号,否则您的表达式将被解析为声明。

(If so, do you think it's ever worthwhile to use this idiom, or is it always clearer to declare the lock in a separate statement?)

我不这么认为,为了获得非常非常少的 yield 而混淆......我总是使用非常明确的锁和非常明确的范围(通常在一个 block 中使用额外的 {}),体面的线程安全代码在没有“特殊”代码的情况下已经足够困难,并且在我看来保证代码非常清晰。

当然是 YMMW :)

关于c++ - 在逗号运算符的 LHS 中初始化匿名互斥锁持有类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1393454/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com