C++11 并发之std::thread std::mutex
https://www.cnblogs.com/whlook/p/6573659.html
(https://www.cnblogs.com/lidabo/p/7852033.html)
C++:线程(std::thread)
1.创建一个线程
创建线程比较简单,使用std的thread实例化一个线程对象就创建完成了,示例:
#include <iostream>
#include <thread>
using namespace std; void t1() //普通的函数,用来执行线程
{
for (int i = ; i < ; ++i)
{
cout << "t1111\n";
}
}
void t2()
{
for (int i = ; i < ; ++i)
{
cout << "t22222\n";
}
}
int main()
{
thread th1(t1); //实例化一个线程对象th1,使用函数t1构造,然后该线程就开始执行了(t1())
thread th2(t2); cout << "here is main\n\n"; return ;
}
不过这个示例是有问题的,因为在创建了线程后线程开始执行,但是主线程main()并没有停止脚步,仍然继续执行然后退出,此时线程对象还是joinable的,线程仍然存在但指向它的线程对象已经销毁,所以会抛出异常。

那么该如何保证子线程执行完了退出后再退出主线程呢?
2.thread::join()
使用join接口可以解决上述问题,join的作用是让主线程等待直到该子线程执行结束,示例:
#include <iostream>
#include <thread>
using namespace std; void t1()
{
for (int i = ; i < ; ++i)
{
cout << "t1111\n";
}
}
void t2()
{
for (int i = ; i < ; ++i)
{
cout << "t22222\n";
}
}
int main()
{
thread th1(t1);
thread th2(t2); th1.join(); //等待th1执行完
th2.join(); //等待th2执行完 cout << "here is main\n\n"; return ;
}
此时就可以正常地执行子线程了,同时注意最后一个输出,说明了main是等待子线程结束才继续执行的

需要注意的是线程对象执行了join后就不再joinable了,所以只能调用join一次。
3.thread::detach()
(1.)中提到的问题,还可以使用detach来解决,detach是用来和线程对象分离的,这样线程可以独立地执行,不过这样由于没有thread对象指向该线程而失去了对它的控制,当对象析构时线程会继续在后台执行,但是当主程序退出时并不能保证线程能执行完。如果没有良好的控制机制或者这种后台线程比较重要,最好不用detach而应该使用join。
int main()
{
thread th1(t1);
thread th2(t2); th1.detach();
th2.detach(); cout << "here is main\n\n"; return ;
}
由结果可见线程并没有执行完而退出:

4.mutex
头文件是<mutex>,mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。
但是使用mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去。
5.std::lock_guard
使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程。示例:
int cnt = ;
mutex m;
void t1()
{
while (cnt > )
{
lock_guard<mutex> lockGuard(m);
if (cnt > )
{
--cnt;
cout << cnt << endl;
} }
}
void t2()
{
while (cnt > )
{
lock_guard<mutex> lockGuard(m);
if (cnt > )
{
--cnt;
cout << cnt << endl;
} }
}
C++11 并发之std::thread std::mutex的更多相关文章
- c++11 Using Callable Objects, std::thread, std::bind, std::async, std::call_once
- C++11 并发指南------std::thread 详解
参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...
- C++11并发——多线程std::thread (一)
https://www.cnblogs.com/haippy/p/3284540.html 与 C++11 多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是< ...
- C++11 并发指南二(std::thread 详解)
上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...
- C++11 并发指南二(std::thread 详解)(转)
上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...
- 【C/C++开发】C++11 并发指南二(std::thread 详解)
上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...
- c++11 跨平台多线程demo和qt 静态链接(std::thread有join函数,设置 QMAKE_LFLAGS = -static)
#include <stdio.h>#include <stdlib.h> #include <chrono> // std::chrono::seconds#in ...
- C++11并发——多线程条件变量std::condition_variable(四)
https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...
- [原]C++新标准之std::thread
原 总结 C++11 thread 概览 std::thread 类定义 各个成员函数的简单介绍 例子 更多 参考资料 概览 从C++11开始提供了线程的支持,终于可以方便的编写跨平台的线程代码了. ...
随机推荐
- ThreadPoolExecutor最佳实践--如何选择线程数
去年看过一篇<ThreadPoolExecutor详解>大致讲了ThreadPoolExecutor内部的代码实现. 总结一下,主要有以下四点: 当有任务提交的时候,会创建核心线程去执行任 ...
- 一篇很好的java异常框架讲解
https://www.cnblogs.com/itcui/p/6400499.html 其实原作者是csdn的一名博主,实在受不了csdn的广告,所以就摘录这篇
- 力扣(LeetCode) 104. 二叉树的最大深度
给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], ...
- Android 关于虹软人脸识别SDK引擎使用总结
虹软 最近开放了人脸识别的SDK引擎(免费的哦),刚好有Android版的,就体验了一波.下面来说说Android版的SDK使用心得: ArcFace 虹软人脸认知引擎简介 目前开放的版本有人脸比对( ...
- 当启动tomcat时出现tomcat setting should be set in tomcat preference page
转自:https://blog.csdn.net/withyou_wy/article/details/53081800 出现此状况证明你的tomcat在配置的时候没有配置成功,通过以下两个步骤即可以 ...
- 使用AutoCloseable 实现自动关闭资源
一.认识AutoCloseable AutoCloseable接口位于java.lang包下,从JDK1.7开始引入. 1.在1.7之前,我们通过try{} finally{} 在finally中释放 ...
- 小程序模板中data传值有无...
A:<template is="gemSelectColor" data="{{optionData}}" />B:<template is= ...
- P5157 [USACO18DEC]The Cow Gathering
首先考虑怎么check一个点是否能被最后一个删除. 可以这么建图,以这个点建有根树,边全部向上指,再加上剩下的有向边. 很明显,这里的一条边的定义就变成了只有删去这个点,才可以删去它指向的点. 因此, ...
- MySQL之库表详细操作
一 库操作 1.创建数据库 1.1 语法 CREATE DATABASE 数据库名 charset utf8; 1.2 数据库命名规则 可以由字母.数字.下划线.@.#.$ 区分大小写 唯一性 不能使 ...
- 384. Shuffle an Array(java,数组全排列,然后随机取)
题目: Shuffle a set of numbers without duplicates. 分析: 对一组不包含重复元素的数组进行随机重排,reset方法返回最原始的数组,shuffle方法随机 ...