gpt4 book ai didi

c++ - 在 C++ 中模拟 C# lock 语句

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:36 24 4
gpt4 key购买 nike

简介:对于同步,C# 提供了 System.Threading.Monitor类,提供线程同步例程,例如 Enter() , Exit() , TryEnter()等等。

此外,还有 lock确保在留下关键代码块时锁被销毁的语句,无论是通过正常执行流程还是通过异常:

private static readonly obj = new Object();

lock(obj) {
...
}

问题:在 C++ 中,为此目的,我们得到了 RAII 包装器 std::lock_guardstd::unique_lock不适用于 Monitor类,但满足 Lockable 的类型概念。但是,我认为这种方法在语法上弱于 C# 实现它的方式,原因如下:

您使用无法重用的变量名污染了局部作用域。这可以通过添加新的范围来解决,例如

  {
std::unique_lock<std::mutex> lck{ mtx };
...
}

但我觉得这个符号看起来很尴尬。更让我烦恼的是这是有效的 C++:

std::unique_lock<std::mutex>{ mtx ]; // note there is no name to the lock!
...

因此,由于忘记给锁守卫一个正确的名称,该语句将被解释为类型为“mtx”的变量声明 std::unique_lock<std::mutex> ,没有锁定任何东西!

我想实现类似 lock 的东西来自 C# 的 C++ 语句。在 C++17 中,这可以很容易地完成:

#define LOCK(mutex) if(std::lock_guard<decltype(mutex)> My_Lock_{ mutex }; true)

std::mutex mtx;
LOCK(mtx) {
...
}

问:如何在 C++11/14 中实现它?

最佳答案

抛开“你应该这样做”,这里是如何:

虽然不完全一样,因为它需要一个分号,但我觉得我可以用分号表示。这个纯 C++14 解决方案基本上只是定义宏来启动一个立即执行的 lambda:

template<typename MTX>
struct my_lock_holder {
MTX& mtx;
my_lock_holder(MTX& m) : mtx{m} {}
};

template<typename MTX, typename F>
void operator+(my_lock_holder<MTX>&& h, F&& f) {
std::lock_guard<MTX> guard{h.mtx};
std::forward<F>(f)();
}

#define LOCK(mtx) my_lock_holder<decltype(mtx)>{mtx} + [&]

my_lock_holder 只是获取互斥锁引用以备后用,并允许我们重载 operator+。这个想法是运算符(operator)创建守卫并执行 lambda。如您所见,该宏定义了一个默认的引用捕获,因此 lambda 将能够引用封闭范围内的任何内容。然后就很简单了:

std::mutex mtx;
LOCK(mtx) {

}; // Note the semi-colon

你可以看到它构建 live .

关于c++ - 在 C++ 中模拟 C# lock 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47602539/

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