问题标签 [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.
c++11 - 为什么 C++ 中 std::mutex 的构造函数不抛出?
该pthread_mutex_init()
函数在初始化互斥锁失败时返回一个非零值,而std::mutex
C++11 中的类具有noexcept
.
假设一个人选择在 pthreads 互斥体之上实现一个 C++ 互斥体类。他在类中包装了一个 pthread 互斥锁,并尝试通过在构造函数中调用 pthread_mutex_init() 来初始化它。如果函数调用返回一个非零值,即错误,由于构造函数不能抛出,所以不能立即报告错误。一种替代方法是在互斥体上实际调用锁定方法之前抛出异常。但这种方法似乎是错误的。
有没有另一种方法来做到这一点,采用一些巧妙的技巧来保证初始化互斥锁总是成功的?
更新:我将在这个问题上回答我自己的问题。根据语言标准,在 30.4.1.3 pge 1163 中,它说“。如果互斥锁类型的对象初始化失败,则应抛出 system_error 类型的异常。”
而noexcept的函数可以在函数体内抛出,只是调用者无法捕捉到异常。如果在 noexcept 函数内抛出异常,则将调用 std::terminate。
c++11 - c++11 std::mutex 锁定同一个线程
我现在正在学习(刷新)C++。作为刷新的一部分,我尝试在std::mutex
下面的代码中检查我的行为。它基本上尝试做'Manual lock
/ unlock
',' std::lock_guard
over mutex
'和' try_lock
over std::mutex
'。当我提到std::mutex::try_lock
时,它说如果同一个线程再次尝试锁定,这是一个死锁。但我正在检查try_lock()
,根据上面的链接描述,它应该给出false
. 但不知何故,std::mutex
能够锁定已经锁定mutex
。我尝试了谷歌搜索/stackoverflow,无法找到导致此行为的原因。你能告诉我,为什么std::mutex
在锁定同一个线程后还能再次锁定?
代码:
编译命令:
输出:
我正在使用的编译器:
c++ - `std::lock_guard 时的不同行为` 对象没有名字
我正在学习std::mutex
,std::thread
我对以下 2 段代码的不同行为感到惊讶:
输出是顺序的。但是如果我不命名变量std::lock_guard<std::mutex>
,则输出是无序的
在第二种情况下似乎std::lock_guard
没有用,为什么?
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::mutex
Windows Vista 的实现基于CRITICAL_SECTION
,但 Win7 及更高版本std::mutex
基于 SWRL。对于 MSVS17 和 15 都是正确的(确保primitives.h
在安装 MSVC++ 时搜索文件并查找stl_critical_section_vista
和stl_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
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()
不会改变任何事情。
为什么两个互斥锁获得锁定的可能性不同,如何使互斥锁以平衡的方式共享?
c++ - 为什么冗余的额外范围块会影响 std::lock_guard 行为?
这段代码演示了互斥锁在两个线程之间共享,但是在thread_mutex
.
(我在另一个问题中有此代码的变体,但这似乎是第二个谜。)
这基本上可以正常工作,但是thread_lock
理论上应该不需要范围块。但是,如果您将其注释掉...
输出是这样的:
即,似乎thread_lock
从不屈服于main_lock
.
如果删除了冗余范围块,为什么thread_lock
总是获得锁并总是等待?main_lock
c++ - 返回时复制操作是在 lock_guard 析构函数之前还是之后执行的?
该get_a()
函数对于竞争条件是否安全,或者我是否需要显式复制str_
才能get_b()
获得线程安全函数?
注意:我知道 Stack Overflow 上有类似的问题,但我找不到明确回答这个问题的问题。
c++ - 如果 std::atomic 仍然需要互斥锁才能正常工作,为什么还要使用它
阅读文本std::condition_variable
我遇到了这句话:
即使共享变量是原子的,也必须在互斥锁下进行修改,才能正确地将修改发布到等待线程。
我的问题是这样的:
如果不是“与 POD 一起使用的无锁代码”,那么原子有什么用?
更新
看起来我的问题有些混乱:(
引用文本中的“共享变量”与“条件变量”不同。请参阅同一页面的此引用:
...直到另一个线程同时修改共享变量(条件),并通知条件变量
请不要回答“为什么我们需要使用带有条件变量的互斥锁”或“条件等待如何工作”,而是提供有关使用互斥锁如何“正确发布”对等待线程的原子修改的信息,即是否需要在互斥锁下完成类似++counter;
(而不是测试)的表达式?if(counter == 0)
c++ - std::atomic_ref 如何为非原子类型实现?
我想知道如何为非原子对象std::atomic_ref
有效地实现(std::mutex
每个对象一个),因为以下属性似乎很难强制执行:
通过 atomic_ref 应用于对象的原子操作相对于通过引用同一对象的任何其他 atomic_ref 应用的原子操作是原子的。
特别是以下代码:
似乎很难实现,因为std::atomic_ref
每次都需要以某种方式选择相同的std::mutex
(除非它是同一类型的所有对象共享的大主锁)。
我错过了什么吗?或者每个对象都负责实现std::atomic_ref
,因此要么是原子的,要么带有std::mutex
?