• STL库跨平台;
  • VS2010不支持std::thread库,至少VS2012/2013及其以上可以;

一、库概要

(1)std::thread成员函数
thread(fun, args...);	//构造函数,传入函数,后面跟参数,若是类普通成员,需要加this指针作为参数1
void swap(thread& other); //线程交换
bool joinable() const; //是否可以加入
void join(); //线程加入线程
void detach(); //线程分离
std::thread::id get_id(); //获取线程id
native_handle_type native_handle(); //获取线程句柄
static unsigned int hardware_concurrency(); //检测硬件并发特性,即最多运行的线程数目

当线程部阻塞运行时,主进程退出而子线程还在运行,则子线程不会退出,变成孤儿线程。

孤儿线程不会造成什么危害,操作系统会对其进行处理,但应尽量避免。

(2)线程中获取线程id
  • 使用this_thread命名空间;
this_thread::get_id();	//获取当前线程的线程id
this_thread::yield();
this_thread::sleep_for();
this_thread::sleep_until();

二、应用示例

(1)创建线程
void fun_1()
{
while (true)
{
cout << "fun_1:" << this_thread::get_id() << endl;
}
}
void fun_2()
{
while (true)
{
cout << "fun_2:" << this_thread::get_id() << endl;
} }
int main()
{
thread t_1(fun_1);
t_1.detach(); thread t_2(fun_2);
t_2.detach(); return 0;
}
(2)类成员作为线程入口 -- 类中创建线程
  • 参数1必须要传,表示当前对象,后面参数表示函数参数;
class TestClass
{
public:
void fun_1_thread_enter()
{
thread t_1(&TestClass::fun1, this, 123);
t_1.detach();
}
void fun_2_thread_enter()
{
thread t_2(&TestClass::fun2, this, 456);
t_2.detach();
}
private:
void fun1(int temp)
{
while (true)
{
cout << "TestClass::fun_1" << this_thread::get_id() << temp << endl;
}
};
void fun2(int temp)
{
while (true)
{
cout << "TestClass::fun_2" << this_thread::get_id() << temp << endl;
}
};
}; int main()
{
TestClass test_class;
test_class.fun_1_thread_enter();
test_class.fun_2_thread_enter(); while (true)
{
cout << "Main thread id:" << this_thread::get_id();
}
return 0;
}
(3)获取CPU最高并发数目
unsigned int num = thread::hardware_concurrency();
(4)线程移动
  • 下例,通过move函数移动线程1到线程2,线程2获得线程1的所有属性;
int main()
{
thread t_1(fun_1);
cout << "Thread 1 id:" << t_1.get_id() << endl; thread t_2 = move(t_1);
cout << "Thread 2 id:" << t_2.get_id() << endl; return 0;
}
(5)延时函数
  • 使用this_thread命名空间中的sleep_for或者sleep_until函数实现等待;
  • std::chrono是一个时间库;
this_thread.sleep_for(chrono::second(2)); //延时2s
this_thread::sleep_for(chrono::milliseconds(5000)); //延时5000ms

三、joindetach

该项为新增项,在发现上文的错误后,新增第三项,而出现错误的原因是,上文参考了很多博客的文章,不是说所有博客的文章都是错的,搜出来的文章很多都是重复或者转载的,第一个写相关文章的人也许是对的,但是随着后来的人,尤其是一知半解的人,再加上自己的理解,难免出现一些偏差,要不是和同事讨论这个问题,也许我都不会发现这个错误。记录下来,作为教训。

上文在修改前有一个错误,join()detach()方法是对线程进行操作,不是开始线程,而在初始化结束后,线程已经开始

看下这两个函数的官方解释:

void join();

Join thread

The function returns when the thread execution has completed.

This synchronizes the moment this function returns with the completion of all the operations in the thread: This blocks the execution of the thread that calls this function until the function called on construction returns (if it hasn't yet).

可见,是说,这个函数知道线程执行完成后才返回,即当调用join()方法时,若线程函数正在执行,则阻塞,若线程函数已经执行完成,则返回。

void detach();

Detach thread

Detaches the thread represented by the object from the calling thread, allowing them to execute independently from each other.

Both threads continue without blocking nor synchronizing in any way. Note that when either one ends execution, its resources are released.

将该线程从创建线程中分离开,让这两个线程各自独立的运行,且各自线程的资源由各自释放。

综上所述,joindetach方法时对线程进行操作,而不是作为线程的开始标志,当申请std::thread资源结束的时候,线程已经开始执行。

那么join还好说,会阻塞主线程,那么detach方法的意义在哪?

如官方说明,这两个线程会在执行结束后各自释放各自的资源,即detach的意义在于资源上。

  • 若并行且不调用detach,则子线程并未从主线程分离,主线程结束后,子线程的资源得不到释放,造成资源泄漏;
  • 使用detach方法,子线程从主线程分离,主线程结束不会关心子线程的状况,子线程结束后,释放子线程的资源;

当然,调用detach方法也有风险,因为子线程从主线程中分离了,若整个程序的主线程都结束而其创建的子线程还在运行,则子线程就变成了孤儿线程。如何避免孤儿线程,相信这不是一个很困难的问题吧。

C++11之STL多线程的更多相关文章

  1. C++11标准 STL正则表达式 验证电子邮件地址

    转自:http://www.cnblogs.com/yejianfei/archive/2012/10/07/2713715.html 我们最经常遇到的验证,就是电子邮件地址验证.网站上常见.各种网页 ...

  2. 浅谈C++11中的多线程(一)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 同步互斥原理以及多进程和多线程中实现同步互斥的两种方法 Qt中的多线程应用 c++ ...

  3. 浅谈C++11中的多线程(三)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 浅谈C++11中的多线程(一) - 唯有自己强大 - 博客园 (cnblogs.c ...

  4. 浅谈C++11中的多线程(二)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 浅谈C++11中的多线程(一) - 唯有自己强大 - 博客园 (cnblogs.c ...

  5. Linux多线程实践(10) --使用 C++11 编写 Linux 多线程程序

    在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程序,从 ...

  6. [转]使用 C++11 编写 Linux 多线程程序

    前言 在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程 ...

  7. 4月11日java多线程4

    继昨天学习了线程池之后,今天学习了多线程内的锁Lock. 定义方法: ReentrantLock queueLock = new ReentrantLock(); //可重入锁 ReentrantRe ...

  8. 进阶系列(11)—— C#多线程

    一.多线程的相关概念 1.进程:是操作系统结构的基础:是一个正在执行的程序:计算机中正在运行的程序实例:可以分配给处理器并由处理器执行的一个实体:由单一顺序的执行显示,一个当前状态和一组相关的系统资源 ...

  9. [转]C++11 多线程

    转载自:http://www.cnblogs.com/zhuyp1015/archive/2012/04/08/2438288.html C++11开始支持多线程编程,之前多线程编程都需要系统的支持, ...

随机推荐

  1. [算法]素数筛法(埃氏筛法&线性筛法)

    目录 一.素数筛的定义 二.埃氏筛法(Eratosthenes筛法) 三.线性筛法 四.一个性质 一.素数筛的定义 给定一个整数n,求出[1,n]之间的所有质数(素数),这样的问题为素数筛(素数的筛选 ...

  2. Julia的基本知识

    知识来源 1.变量.整数和浮点数 Julia和Matllab挺像的,基本的变量,数值定义都差不多,所以就没必要记录了. 2.数学运算 3.函数

  3. div3--C. Pipes

    题目链接:https://codeforces.com/contest/1234/problem/C 题目大意:根据规则,判断是否可以从左上走到右下,1,2,3,4,5,6分别对应题干给的图片,所以1 ...

  4. A 蚂蚁觅食

    A. 蚂蚁觅食(一) 单点时限: 1.0 sec 内存限制: 512 MB 一只饥饿的小蚂蚁外出觅食,幸运的小蚂蚁发现了好多食物,但是它只有一次搬食物的机会.可因为力气太小了,它不能搬走重量超过自己体 ...

  5. jarvisoj MISC 取证2

    打开之后一个文件和一个镜像 TrueCrypt....记住他了,再看一眼那个文件,好的,TrueCrypt加密..找密码 把Truecrypt.exe直接dump下来,用efdd解密就行了

  6. jmeter json path espressions学习

    jsonpath表达式可以使用点或者括号来取值 管方详细介绍:https://goessner.net/articles/JsonPath/ $ :表示根对象 @:表示当前对象 . 或者[]:表示子运 ...

  7. python学习笔记(一)---字符串与列表

    字符串的一些处理 字符串的大小写 name="lonmar hb" print(name.upper())#全大写 print(name.lower())#全小写 print(na ...

  8. tp5.1 模型 where多条件查询 like 查询

    来源:https://blog.csdn.net/qq_41241684/article/details/87866416 所以我改成这样: $paperTypeModel = new PaperTy ...

  9. SESSION劫持

    服务端和客户端之间是通过session(会话)来连接沟通.当客户端的浏览器连接到服务器后,服务器就会建立一个该用户的session.每个用户的session都是独立的,并且由服务器来维护.每个用户的s ...

  10. Ubuntu忘记超级用户root密码,重新设置密码 转载

    原文链接:https://blog.csdn.net/weixin_37909391/article/details/80691601 Ubuntu版本:Ubuntu 16.04.3 LTS 1启动系 ...