问题标签 [lock-guard]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
76 浏览

c++ - 使用 lock_guard 采用的互斥锁可以导致 UB 吗?

由于使用已被 a 采用的互斥锁的锁,以下代码段是否会导致未污染的行为 a lock_guard?如果我在同一个片段中使用unique_lock而不是它会安全吗?lock_guard我知道有std::unique_lock<T>::lock/unlock()

0 投票
2 回答
228 浏览

c++ - c++11: thread with mutex sees atomic variable's value changing despite this being the only code that can change it

An atomic variable (128-bit structure in this case) is being updated, to the surprise of the only thread that would have the ability to update it. How so?

This is a minimal example so it doesn't do anything that makes sense, but: an alloc() function returns a malloc'd buffer 100 times, then allocates a new buffer it will return 100 times, and so on, even in the face of being called with multiple threads.

I have an atomic variable, which is a structure with a pointer, a 32-bit int, and another 32-bit counter meant to avoid ABA problems.

I have a function with two sections. The first section will, if the return count is non-zero, CAS the struct to decrement the return count (and increment the ABA counter), then return the pointer. Otherwise, the second section gets a mutex, allocates memory for a new pointer, and CAS's the little struct completely with the new pointer, a new non-zero return counter, and again an increment to the ABA counter.

In short, every thread can update this struct when the counter is above zero. But once it's zero, the first thread to avquire the mutex will, I think, be the only thread that can again CAS update this struct.

Except sometimes this CAS fails! "How can it fail" is my question.

Here is a running example. It can be compiled with g++ lockchange.cxx -o lockchange -latomic -pthread . It runs on gcc version 9.2.1 20190827 (Red Hat 9.2.1-1) (GCC) on Fedora 31.

0 投票
1 回答
315 浏览

c++ - 在这种情况下我应该使用 lock_guard、scoped_lock 还是 unique_lock?

我已经阅读了许多已经回答的与此相关的问题,但没有一个让我清楚地了解当我有多个作家但只有一​​个读者时应该使用哪个。下面的代码是我所说的一个人为的例子。

情况是多个编写者可能同时更新 stateInfo 向量,但向量中的项目绝不会与i每个线程唯一的项目相同。单个读取器线程可以随时尝试读取任何向量项。

  1. 上面的代码在避免竞争条件方面是否正确?

  2. lock_guard正确的使用还是我应该使用scoped_lockor unique_lock

0 投票
0 回答
45 浏览

c++ - 从锁下返回引用:惯用的还是太聪明了?

假设您有一个数据结构,其中值保存在节点中,例如标准映射或列表,并且该结构有一个锁来保护它。假设值类型(mapped_type用于映射)足够复杂,每个都有自己的锁。

所以基本操作就是获取地图的锁,获取(引用)值,然后解锁地图的锁。现在,您可以根据需要锁定该值的锁并参与其中。

问题 - 如我所见 - 是您无法分配引用 - 只能初始化它。所以我提出了以下类型的代码,给定一些M带有实例的映射类型m(它是 mutex m_mutex):

这就是您可以at用来添加元素的情况。如果您不想这样做,您可以:

好主意还是太聪明而无法通过代码审查?在现代 C++ 中执行此操作的惯用方式是什么?

0 投票
0 回答
46 浏览

c++ - 使用 lock_guard 同时从多个线程访问同一对象时出现问题

我正在使用 lock_guard 在访问子跟踪器的对等方之间进行同步。有一些对等点,其中一个对等点也是子跟踪器。subtrackergetPeer()方法的工作是计算最近的对等点,其中包含请求对等点需要的某个数据包。中基本上需要同步packetToPeersMapping,其中包含有关具有特定数据包的对等方的信息。每个对等点都是一个单独的线程,并分配有一个子跟踪器。

理想情况下,如果一个对等点需要一个数据包,它将调用该getPeer()方法并返回最近的对等点。在运行代码时,有时即使当前对等方没有必要的数据包,该getPeer()方法也会返回当前对等方作为最近的对等方拥有数据包。我认为我使用lock_guard的方式有问题

0 投票
1 回答
94 浏览

c++ - 如何仅将互斥锁传递给 lock_guard 构造函数参数

像申报储物柜时,


我希望编译器检测 mLocker 是否是互斥锁。

为了实现这一点,我使用了概念要求并定义如下。


如上所述,互斥锁针对类型 T 进行了验证,并且类型 T 的 std::lock_guard 通过使用关键字进行了别名。

但是当使用该别名(expLock)声明一个储物柜时。


上面的代码会导致编译错误。

似乎 std::lock_guard 构造函数的显式关键字被忽略了,因为下面的代码将类型 T 强制为 std::lock_guard。


当然,如果在 alias(expLock) 中指定类型 T 如下所示,则不会出现编译错误。


但我希望下面的代码能够在没有编译错误的情况下工作。


如何仅将互斥锁传递给 lock_guard 构造函数参数?

我应该定义一个像 std::lock_guard 这样的新 Locker 类吗?或者我需要修复别名吗?

也是这样还是有新的解决方案?



这个问题已经在下面的评论中得到了回答。

根据 cppreference,MSVC 在 19.27* 之后实现了 P1814,所以如果您的 MSVC 版本比 19.27* 新,您的代码将在使用 /std:c++latest 标志时编译。——康桓玮</p>

如果当前项目的 MSVC 是 19.27 或更高版本,则可以省略 using 关键字的模板参数列表。但是,如果您使用 Visual Studio 的 Intellisense,Intellisense 可能会显示错误消息。如果在 MSVC 19.27 或更高版本中弹出 using 关键字的模板参数列表错误消息,则该错误消息可能是由于 Intellisense 补丁不基于 MSVC 版本。除了 Intellisense 弹出的错误消息外,构建工作没有任何问题。- 정명준

0 投票
0 回答
49 浏览

c++ - 作用域 lock_guard 不释放静态方法中的互斥锁

平台 Debian 9 | 手臂

我有一个用于在 a 上存储线程 ID 的类,std::list然后将列表打印为关闭过程的一部分。有两种静态方法:AddId()PrintIds()。由于静态方法由多个线程使用,因此列表访问受到保护std::mutex。我遇到了两个让我感到困惑的问题,它们可能是相关的。我希望你们中的一个可以帮助解释我所缺少的。

注意我首先使用了 scoped s,并且出于此处解释的原因std::lock_guard<std::mutex>暂时选择了代码中显示的 s。std::unique_lock<std::mutex>

问题 1 程序启动时,所有线程都会调用ThreadMgr::AddId(),这会将线程 ID 和字符串名称一起添加到列表中。这似乎工作正常。但是,ThreadMgr::PrintIds()在关闭过程中调用时,std::mutex仍然被锁定并std::lock_guard阻塞。在测试时,我解锁了std::mutex前面的行中的- 如果它没有被调用线程锁定,这std::lock_guard未定义的行为- 然后它按预期工作。唯一std::mutex使用的地方是在这两个方法中,并且在std::lock_guard作用域中,std::mutex应该在每次方法调用时解锁。我经历了几次std::mutex直接锁定和解锁的迭代,使用std::unique_lockstd::unique_locks 等。我最终使用此处提供的代码中的 s 找到了一个可行的解决方案。然而,这也让我感到困惑。

std::unique_lock如果我使用 s 工作,std::adopt_lock但仅限于ThreadMgr::PrintIds(). 如果我使用std::adopt_lockin ThreadMgr::AddId(),那么无论何时ThreadMgr::PrintIds()调用都会出现分段错误。

问题 2如前所述,当所有线程在启动时调用它时ThreadMgr::AddId()运行良好。但是,在某些 UI 会话中,每个会话都会产生一个线程。当从这些会话线程之一调用时,两者和块都已经锁定。因此,对于其他所有线程都可以正常工作,但不适用于稍后启动的会话线程。std::lock_guardstd::unique_lockThreadMgr::AddId()std::lock_guardstd::unique_lockstd::mutexThreadMgr::AddId()

如果我可以提供任何其他信息来帮助找到解决方案,请告诉我。