• 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. IOCP完成端口

    转:https://blog.csdn.net/piggyxp/article/details/6922277 本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所 ...

  2. [bilibili服]明日方舟游戏时长限制破解

    bilibili服 明日方舟 游戏时长如何破解 众所周知,明日方舟游戏对未成年人实行了游戏时长限制,小编也感到十分惊讶--咳咳--言归正传--之前在网上看到过有说可以通过进入战斗之后断网来实现延长时间 ...

  3. vue2.x学习笔记(九)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12577948.html. 数组的更新检测 数组在javascript是一种特殊的对象,不是像普通的对象那样通过Ob ...

  4. 【半译】在ASP.NET Core中创建内部使用作用域服务的Quartz.NET宿主服务

    在我的上一篇文章中,我展示了如何使用ASP.NET Core创建Quartz.NET托管服务并使用它来按计划运行后台任务.不幸的是,由于Quartz.NET API的工作方式,在Quartz作业中使用 ...

  5. 吃瓜的正确姿势,Python绘制罗志祥词云图

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 这篇文章中向大家介绍了Python绘制词云的方法,不难看出绘制词云可以说是一 ...

  6. redis: Set集合类型(五)

    Set里面的值是不能重复的 Set设置值(头部):sadd myset hello Set获取值:smembers myset 检查Set是否包含某个元素:sismember myset hello ...

  7. redis的多路复用是什么鬼

    有没有人和我一样, 自打知道了redis, 就一直听说什么redis单线程, 使用了多路复用等等. 天真的我以为多路复用是redis实现的技术. 今天才发现, 我被自己骗了, 多路复用是系统来实现的. ...

  8. HTML+CSS教程(二)frameset框架和iframe内嵌

    一.框架 (frameset)1.用<frameset></frameset>代替了<body></body>2.rows设置行的占页面的百分比:col ...

  9. js 一个或多个一维数组,算出元素之间相互组合的所有情况

    // 数据源 var target = { state1: ['1', '2'], state2: ['01', '02', '03'], state3: ['001','002'] } stackS ...

  10. c++四舍五入函数round()

    其实c++自身是没有四舍五入函数round()的,若果你要用到的话,可以自己写一个round(),不过要用到floor()和ceil这两个函数如下: #include<iostream> ...