问题标签 [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 投票
1 回答
2381 浏览

c++ - 使用 std::mutex 发布和获取

这是关于 C++ 标准的问题。我只能访问标准草案,所以如果这与官方标准不同,我深表歉意。另外,如果我误解了它的工作原理,请随时纠正我。

假设我有两个线程,一个写入字符串,一个复制该字符串的内容。我使用std::mutex myMutex; 我知道您通常应该将 RAII 类用于锁来保护对它们的访问,我只是显式地使用了 lock 和 unlock 以使示例更加明确。

我的理解是,为了在线程之间可靠地工作,线程一必须在设置字符串后执行释放操作,而线程二必须在读取字符串之前执行获取操作。

阅读 C++11 的标准草案,我看不到任何说明这样std::mutex做的内容,尽管很明显它是预期的,否则互斥锁对任何事情都无用。

有人可以将我指向相关部分以查看吗?对于普通读者来说,标准中的措辞通常并不完全清楚:)

0 投票
7 回答
192817 浏览

c++ - std::unique_lock或 std::lock_guard?

我有两个用例。

A. 我想同步访问两个线程的队列。

B. 我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。

对于用例 AI,请参阅使用std::lock_guard<>. 对于用例 BI,请参阅使用std::unique_lock<>.

两者之间有什么区别,我应该在哪个用例中使用哪一个?

0 投票
4 回答
5934 浏览

c++ - 我的等待 - 使用 std::mutex 的通知机制是否正确?

我开始使用 std::mutexes 来停止一个线程并等待另一个线程恢复它。它是这样工作的:

线程 1

线程 2

但是我不确定这是否正确并且在所有平台上都可以正常工作。如果这不正确,那么在 C++11 中实现它的正确方法是什么?

0 投票
2 回答
1055 浏览

c++ - 使用 std::atomic 的正确性结合 std::mutex

我写了一个共享优先级队列类。
为了发出停止提供数据的信号,我使用方法Cancel(),它将标志设置done为 false,并且不允许应用程序从队列中写入/读取任何数据。我不确定与andstd::atomic<bool>结合使用。我不确定,如果我的解决方案是线程安全的或可能发生竞争条件:std::mutexstd::condition_variable

方法的原始版本Enqueue是:

但是,可以done通过互斥锁将变量(原子布尔)与锁定机制分开吗?

要取消队列,我使用此构造:

以下设计的最佳解决方案是什么?

等候人员:

0 投票
2 回答
5500 浏览

c++ - 是否有任何理由应该将 C++ 11+ std::mutex 声明为全局变量,而不是作为函数参数传递给 std::thread ?

我见过大多数使用std::mutex互斥锁是全局的例子。我想知道这样做有什么具体原因吗?我有自己的程序,但我不这样做,只需将互斥锁作为std::thread std::ref. 拥有全局变量不是不好的做法,std::mutexes如果没有语言限制这样做的理由,C++ 中全局变量背后的原因是什么?

0 投票
1 回答
8874 浏览

c++11 - 使用 std::mutex 作为类中的成员变量

我已经定义了一个具有std::mutex my_mutex作为其私有成员变量的类。但是当我尝试在从不同线程调用的成员函数中使用它时lock_guard,编译器会抛出很多错误。如果我把这个互斥锁放在课堂之外,它就可以工作。代码如下

如果将相同my_mutex的内容保留在课堂之外,那么它可以正常工作。那么当同一个变量在类中并在线程所作用的成员函数中调用时,它是否像静态成员一样对待?

0 投票
1 回答
1348 浏览

c++ - 为什么使用 std::mutex 的函数对 pthread_key_create 的地址进行空检查?

采用这个简单的函数,它在由实现的锁下递增一个整数std::mutex

我希望这(在内联之后)以一种直接的方式编译为调用thenm.lock()的增量。im.unlock()

gcc但是,检查生成的程序集是否有和的最新版本clang,我们会发现一个额外的复杂问题。先取gcc版本:

有趣的是前几行。组装后的代码检查地址__gthrw___pthread_key_create(它是pthread_key_create创建线程本地存储键的函数的实现),如果它为零,它会分支到.L2在单个指令中实现增量而根本没有任何锁定的地址。

如果它不为零,它会按预期进行:锁定互斥体,执行增量,然后解锁。

clang做得更多:它检查函数的地址两次,一次在 the之前,一次在 thelock之前unlock

这次检查的目的是什么?

也许是为了支持目标文件最终编译成没有 pthreads 支持的二进制文件,然后在这种情况下回退到没有锁定的版本的情况?我找不到有关此行为的任何文档。

0 投票
3 回答
4850 浏览

c++ - 共享内存中的 std::mutex 不起作用

我有一个场景,共享内存区域由两个不同的进程独占访问。当我启动进程时,第一个进程成功锁定互斥锁,更新内存并解锁互斥锁。但是我观察到,当第二个进程尝试锁定它时,它仍然处于死锁状态,等待互斥锁解锁。

第一个进程和第二个进程的互斥锁时间差为 10 秒。

我正在使用 std::mutex。请告诉我我错过了什么。

0 投票
1 回答
145 浏览

c++ - c++ 线程安全和时间效率:为什么带互斥检查的线程有时比没有它的工作得更快?

我是 C++ 中线程使用的初学者。我已经阅读了有关 std::thread 和互斥锁的基础知识,似乎我了解使用互斥锁的目的。

我决定检查没有互斥锁的线程是否真的如此危险(好吧,我相信书,但更喜欢亲眼看到它)。作为“我将来不应该做的事情”的测试用例,我创建了相同概念的 2 个版本:有 2 个线程,其中一个将一个数字递增数次(NUMBER_OF_ITERATIONS),另一个将相同的数字递减相同的数量次,因此我们希望在代码执行后看到与之前相同的数字。附上代码。

起初,我运行 2 个线程,它们以不安全的方式执行 - 没有任何互斥锁,只是为了看看会发生什么。在这部分完成后,我运行 2 个线程,它们做同样的事情,但以安全的方式(使用互斥锁)。

预期结果:如果没有互斥锁,结果可能与初始值不同,因为如果两个线程同时使用数据可能会损坏数据。尤其是对于巨大的 NUMBER_OF_ITERATIONS 来说这是很常见的——因为损坏数据的可能性更高。所以这个结果我可以理解。

我还测量了“安全”和“不安全”部分花费的时间。正如我所料,对于大量迭代,安全部分花费的时间比不安全部分要多得多:互斥检查花费了一些时间。但是对于少量迭代(400、4000),安全部分执行时间小于不安全时间。为什么会这样?它是操作系统所做的事情吗?或者编译器是否有一些我不知道的优化?我花了一些时间思考它,并决定在这里问。

我使用 windows 和 MSVS12 编译器。

因此问题是:为什么安全部分的执行可能比不安全部分的第一部分更快(对于小的 NUMBER_OF_ITERATIONS < 1000*n)? 另一个:为什么它与NUMBER_OF_ITERATIONS有关:对于较小的(4000)带有互斥锁的“安全”部分更快,但对于大型(400000)的“安全”部分较慢?

主文件

0 投票
0 回答
196 浏览

multithreading - 一个线程中应该使用多少互斥锁

我正在处理一个 c++ (11) 项目,在主线程上,我需要检查两个变量的值。这两个变量的值将由其他线程通过两个不同的回调来设置。我正在使用两个条件变量来通知这两个变量的变化。因为在 C++ 中,条件变量需要锁,我不确定是否应该为两个条件变量使用相同的互斥锁,或者我应该使用两个互斥锁来最小化独占执行。不知何故,我觉得一个互斥体就足够了,因为在一个线程(在这种情况下为主线程)上,代码无论如何都会按顺序执行。检查(等待)两个变量值的主线程上的代码无论如何都不会交错。如果您需要我编写代​​码来说明问题,请告诉我。我可以准备那个。谢谢。

更新,添加代码: