• 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

三、join和detach

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

上文在修改前有一个错误,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.

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

综上所述,join和detach方法时对线程进行操作,而不是作为线程的开始标志,当申请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. 如果我选择IT行业,会不会在几年,或者几年后被社会给淘汰??

    IT互联网各行业薪资占比,你能拿到多少?随着移动互联网时代的发展,IT行业的需求量也越来越大,而且每年都会新增,当然也会有淘汰. 人生如此之短,都不喜欢自己虚度光阴,也不希望自己所努力的东西成为历史, ...

  2. Cobalt Strike系列教程第七章:提权与横向移动

    Cobalt Strike系列教程分享如约而至,新关注的小伙伴可以先回顾一下前面的内容: Cobalt Strike系列教程第一章:简介与安装 Cobalt Strike系列教程第二章:Beacon详 ...

  3. frame/iframe多表单切换

    应用场景: 在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位.这时就 ...

  4. [linux] 小问题:管道符,换行问题等;[nginx]启动,重启,关闭命令;以及升级nginx切换命令

    Lniux换行问题 后面回车不会马上执行本条命令而是换行继续. : 是运行完前面就继续后面的, && 同样是前面正确就运行后面, || 是前面运行不正确就运行后面. | 管道符“|”将 ...

  5. Springboot:异步业务处理(十二)

    说明 当正常业务处理调用一个复杂业务或者耗时较长的请求时,客户等待时间会比较长,造成不好的用户体验,所以这时候需要用的异步处理 构建一个群发邮件的service接口及实现(模拟) 接口:com\spr ...

  6. TensorFlow命令行参数FLAGS使用

    import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf #tensorboard --logdir=&qu ...

  7. 安卓微信浏览器中window.location.href失效的问题

    最近接手一微信项目,测试功能时,发现跳转在android手机上不动了.iso系统可以正常跳转的.解决方法: window.location.href = url + '?v=' + (new Date ...

  8. Linux查看端口或pid使用路径

    1. lsof -i:10010 查看10010端口的占用情况 命令返回结果: 2. netstat -lpn | grep 80 查看80端口服务端socket占用状况 3. ll /proc/26 ...

  9. 2019-2020-1 20199325《Linux内核原理与分析》第四周作业

    start_kernel函数的执行过程 asmlinkage __visible void __init start_kernel(void) { char *command_line; char * ...

  10. [Inno Setup] 执行程序,返回值不为0时提示用户

    procedure LoadPerfCounter(); var Ret : Integer; begin if Exec(ExpandConstant('{sys}') + '\lodctr.exe ...