将 std::thread 与 std::mutex 一起使用
Posted
技术标签:
【中文标题】将 std::thread 与 std::mutex 一起使用【英文标题】:Using std::thread with std::mutex 【发布时间】:2014-10-20 04:51:20 【问题描述】:我正在尝试使用独立线程进行互斥锁。要求是,我有许多线程将独立运行并访问/更新公共资源。为了确保通过单个任务更新资源,我使用了互斥锁。然而,这是行不通的。
我已经粘贴了代码,这是我在下面尝试做的一个表示:
#include <iostream>
#include <map>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <unistd.h>
std::mutex mt;
static int iMem = 0;
int maxITr = 1000;
void renum()
// Ensure that only 1 task will update the variable
mt.lock();
int tmpMem = iMem;
usleep(100); // Make the system sleep/induce delay
iMem = tmpMem + 1;
mt.unlock();
printf("iMem = %d\n", iMem);
int main()
for (int i = 0; i < maxITr; i++)
std::thread mth(renum);
mth.detach(); // Run each task in an independent thread
return 0;
但这会因以下错误而终止:
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
我想知道上面
【问题讨论】:
当您从main()
返回时,进程将退出,因此线程中尚未完成的任何工作都不会完成。等待他们使用join()
是main()
在返回之前做的一件完美的事情。
一 千 个线程似乎有点过头了。试着用一些可管理的东西来解决这个问题; (如 3)。而且你没有在等待你的线程,所以一旦你完成抛出线程main()
就会终止,完成你的进程;可能不是你想要的。为此,我建议线程分离是错误的。相反,您应该将它们强加到std::vector<>
,然后在main()
终止之前加入它们全部。
@MichaelBurr 感谢您的评论。那么如果我使用.join(),每个线程是独立运行还是等待前一个线程完成?我的要求是每个线程都应该独立运行。感谢您的帮助。
警告,你正在用你的 printf 在锁外阅读iMem
。
[OT]:您可以使用std::lock_guard
(或std::unique_lock
)代替锁定/解锁自己。或者也许使用std::atomic
。
【参考方案1】:
试试这个:
int main()
std::vector<std::thread> mths;
mths.reserve(maxITr);
for (int i = 0; i < maxITr; i++)
mths.emplace_back(renum);
for (auto& mth : mths)
mth.join();
这样,您可以保留对线程的控制(通过不调用detach()
),并且您可以在最后加入它们,这样您就知道它们已经完成了任务。
【讨论】:
谢谢。我需要 1 澄清。 thread.join() 会让每个任务独立运行还是所有剩余任务都必须等待主任务完成(.join())? 线程将被允许独立运行和完成,除了等待所有线程的主线程(具体来说,它将等待mths[0]
完成,然后等待@987654324 @ 完成,等等,但当然线程可以按任何顺序完成。
您是说 mths[1] 将仅在 mths[0] 完成后运行,而与访问共享对象无关?或者两者都将并行运行,但在访问共享资源 (iMem) 时,mths[1] 将等待 mths[0] 从 iMem 对象中释放锁?
线程并发运行;唯一的序列化部分是您按顺序join()
他们。这一切都很好。无法保证哪个线程将“首先”执行。以上是关于将 std::thread 与 std::mutex 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
mingw std::thread 与 Windows API
C++11 多线程std:: async与std::thread的区别
具有与 std::thread 不同的线程库的 C++ thread_local
使用std :: thread将多个线程的数组组合在一起使用std :: thread