问题标签 [stdmutex]

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 投票
4 回答
1860 浏览

c++11 - 为什么 C++ 中 std::mutex 的构造函数不抛出?

pthread_mutex_init()函数在初始化互斥锁失败时返回一个非零值,而std::mutexC++11 中的类具有noexcept.

假设一个人选择在 pthreads 互斥体之上实现一个 C++ 互斥体类。他在类中包装了一个 pthread 互斥锁,并尝试通过在构造函数中调用 pthread_mutex_init() 来初始化它。如果函数调用返回一个非零值,即错误,由于构造函数不能抛出,所以不能立即报告错误。一种替代方法是在互斥体上实际调用锁定方法之前抛出异常。但这种方法似乎是错误的。

有没有另一种方法来做到这一点,采用一些巧妙的技巧来保证初始化互斥锁总是成功的?

更新:我将在这个问题上回答我自己的问题。根据语言标准,在 30.4.1.3 pge 1163 中,它说“。如果互斥锁类型的对象初始化失败,则应抛出 system_error 类型的异常。”

而noexcept的函数可以在函数体内抛出,只是调用者无法捕捉到异常。如果在 noexcept 函数内抛出异常,则将调用 std::terminate。

0 投票
0 回答
1291 浏览

c++11 - c++11 std::mutex 锁定同一个线程

我现在正在学习(刷新)C++。作为刷新的一部分,我尝试在std::mutex下面的代码中检查我的行为。它基本上尝试做'Manual lock/ unlock',' std::lock_guardover mutex'和' try_lockover std::mutex'。当我提到std::mutex::try_lock时,它说如果同一个线程再次尝试锁定,这是一个死锁。但我正在检查try_lock(),根据上面的链接描述,它应该给出false. 但不知何故,std::mutex能够锁定已经锁定mutex。我尝试了谷歌搜索/stackoverflow,无法找到导致此行为的原因。你能告诉我,为什么std::mutex在锁定同一个线程后还能再次锁定?

代码:

编译命令:

输出:

我正在使用的编译器:

0 投票
1 回答
954 浏览

c++ - `std::lock_guard 时的不同行为` 对象没有名字

我正在学习std::mutexstd::thread我对以下 2 段代码的不同行为感到惊讶:

输出是顺序的。但是如果我不命名变量std::lock_guard<std::mutex>,则输出是无序的

在第二种情况下似乎std::lock_guard没有用,为什么?

0 投票
1 回答
1695 浏览

c++ - 为什么 CRITICAL_SECTION 性能在 Win8 上变差了

似乎 CRITICAL_SECTION 性能在 Windows 8 及更高版本上变得更糟。(见下图)

测试非常简单:一些并发线程每个执行 300 万个锁来独占访问一个变量。您可以在问题的底部找到 C++ 程序。我在 Windows Vista、Windows 7、Windows 8、Windows 10(x64、VMWare、Intel Core i7-2600 3.40GHz)上运行测试。

结果如下图所示。X 轴是并发线程数。Y 轴是以秒为单位的经过时间(越低越好)。

试验结果

我们可以看到:

  • SRWLock所有平台的性能大致相同
  • CriticalSection在 Windows 8 及更高版本上,性能相对 SRWL 变得更差

问题是:谁能解释为什么 CRITICAL_SECTION 性能在 Win8 及更高版本上变得更差?


一些注意事项:

  • 真实机器上的结果几乎相同 - CS 在 Win8 及更高版本上比 std::mutex、std::recursive_mutex 和 SRWL 差得多。但是我没有机会在具有相同 CPU 的不同操作系统上运行测试。
  • std::mutexWindows Vista 的实现基于CRITICAL_SECTION,但 Win7 及更高版本std::mutex基于 SWRL。对于 MSVS17 和 15 都是正确的(确保primitives.h在安装 MSVC++ 时搜索文件并查找stl_critical_section_vistastl_critical_section_win7类)这解释了 Win Vista 和其他系统上 std::mutex 性能之间的差异。
  • 正如评论中所说,这std::mutex是一个包装器,因此对于一些相对于SRWL的开销的可能解释可能是包装器代码引入的开销。

测试项目在 Microsoft Visual Studio 17 (15.8.2) 上构建为 Windows 控制台应用程序,具有以下设置:

  • MFC 的使用:在静态库中使用 MFC
  • Windows SDK 版本:10.0.17134.0
  • 平台工具集:Visual Studio 2017 (v141)
  • 优化:O2、Oi、Oy-、GL
0 投票
2 回答
521 浏览

c++ - 为什么 std::mutex 需要很长时间才能共享?

这段代码演示了互斥锁在两个线程之间共享,但一个线程几乎一直拥有它。

在 Ubuntu 18.04 4.15.0-23-generic 上使用 g++ 7.3.0 编译。

输出是#.字符的混合,表明互斥体正在共享,但模式令人惊讶。通常是这样的:

thread_lock锁定互斥锁长时间。几秒甚至几十秒后,接收方main_lock(短暂地)接收控制权,然后thread_lock将其取回并保留很长时间。打电话std::this_thread::yield()不会改变任何事情。

为什么两个互斥锁获得锁定的可能性不同,如何使互斥锁以平衡的方式共享?

0 投票
2 回答
129 浏览

c++ - 为什么冗余的额外范围块会影响 std::lock_guard 行为?

这段代码演示了互斥锁在两个线程之间共享,但是在thread_mutex.

(我在另一个问题中有此代码的变体,但这似乎是第二个谜。)

这基本上可以正常工作,但是thread_lock理论上应该不需要范围块。但是,如果您将其注释掉...

输出是这样的:

即,似乎thread_lock从不屈服于main_lock.

如果删除了冗余范围块,为什么thread_lock总是获得锁并总是等待?main_lock

0 投票
1 回答
341 浏览

c++ - 返回时复制操作是在 lock_guard 析构函数之前还是之后执行的?

get_a()函数对于竞争条件是否安全,或者我是否需要显式复制str_才能get_b()获得线程安全函数?

注意:我知道 Stack Overflow 上有类似的问题,但我找不到明确回答这个问题的问题。

0 投票
2 回答
844 浏览

c++ - 如果 std::atomic 仍然需要互斥锁才能正常工作,为什么还要使用它

阅读文本std::condition_variable我遇到了这句话:

即使共享变量是原子的,也必须在互斥锁下进行修改,才能正确地将修改发布到等待线程。

我的问题是这样的:

如果不是“与 POD 一起使用的无锁代码”,那么原子有什么用?

更新

看起来我的问题有些混乱:(

引用文本中的“共享变量”与“条件变量”不同。请参阅同一页面的此引用:

...直到另一个线程同时修改共享变量(条件),并通知条件变量

请不要回答“为什么我们需要使用带有条件变量的互斥锁”或“条件等待如何工作”,而是提供有关使用互斥锁如何“正确发布”对等待线程的原子修改的信息,即是否需要在互斥锁下完成类似++counter;而不是测试)的表达式?if(counter == 0)

0 投票
3 回答
112 浏览

c++ - 有必要锁吗?

我在leetcode中遇到了一个问题。我在讨论中查看了一些解决方案。但我的解决方案与其他解决方案不同,因为我没有使用lockin 方法first。我想知道我的代码是否正确。此外,你能给我一些关于我的代码的建议吗?

我认为没有必要在类似unique_lock的方法中使用,对吗?void first(function<void()> printFirst)void second(function<void()> printSecond)

0 投票
2 回答
462 浏览

c++ - std::atomic_ref 如何为非原子类型实现?

我想知道如何为非原子对象std::atomic_ref有效地实现(std::mutex每个对象一个),因为以下属性似乎很难强制执行:

通过 atomic_ref 应用于对象的原子操作相对于通过引用同一对象的任何其他 atomic_ref 应用的原子操作是原子的。

特别是以下代码:

似乎很难实现,因为std::atomic_ref每次都需要以某种方式选择相同的std::mutex(除非它是同一类型的所有对象共享的大主锁)。

我错过了什么吗?或者每个对象都负责实现std::atomic_ref,因此要么是原子的,要么带有std::mutex?