• 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. Sentry实时应用错误跟踪系统在Kubernetes中私有化部署

    应用错误跟踪系统:对软件系统运行过程中产生的错误日志进行收集从而实现监控告警. 虽然软件错误❌是不可避免的,但是可以降低错误数. 提高对错误的治理能力能让错误带来的损失降到最低 ​

  2. jdk动态代理:由浅入深理解mybatis底层

    什么是代理 代理模式,目的就是为其他对象提供一个代理以控制对某个对象的访问,代理类为被代理者处理过滤消息,说白了就是对被代理者的方法进行增强. 看到这里,有没有感觉很熟悉?AOP,我们熟知的面向切面编 ...

  3. jquary 动画j

    1) 点击 id为d1的正方体,将其后所有class为div1的正方体背景色设置为绿色. 代码如下:       <div class="div1" > </di ...

  4. 初识phar反序列化&&复现bytectf_2019_easycms&&RSS思路

    概要 来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞.这个新的攻击方式被他公开在了 ...

  5. 【学习笔记】splay入门(更新中)

    声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 前言 终于学习了 spaly \(splay\) !听说了很久,因为dalao总 ...

  6. 基于spring的安全管理框架-Spring Security

    什么是spring security? spring security是基于spring的安全框架.它提供全面的安全性解决方案,同时在Web请求级别和调用级别确认和授权.在Spring Framewo ...

  7. vscode--常用插件&同步

    1.setting.json文件 { "files.autoSave": "off", "extensions.ignoreRecommendatio ...

  8. RSA,AES加解密算法的实现

    目录 Python实现RSA公钥加密算法 RSA公钥加密算法原理 RSA算法的Python实现 AES加解密算法实现 AES加解密算法原理 AES加解密算法Python实现 参考文献 Python实现 ...

  9. Kubernetes 命令行工具之kubctl

    目录 1.何为kubectl 2.Kubectl基本使用 2.1.命令补全 2.2.快速查找资源 2.3.使用自定义输出格式 3.陈述式管理资源 3.1.管理namespace资源 3.2.管理Dep ...

  10. 理解分布式一致性:Raft协议

    理解分布式一致性:Raft协议 什么是分布式一致性 Leader选举 日志复制流程 term选举周期 timeout 选举和选举timeout 选举分裂 日志复制和心跳timeout 在分布式系统中, ...