std::thread线程详解(1)
目录
简介
本文主要介绍了标准库中的线程部分。线程是目前多核编程里面最重要的一部分。
与进程进程相比,其所需的资源更少,线程之间沟通的方法更多; 他们之间的区别可以比较简明用以下几点概括[1]:
- 进程是资源分配的最小单位,线程是CPU调度的最小单位;也就是说进程之间的资源是相互隔离,而线程之间的是可以相互访问的。
- 线程的存在依赖于进程,一个进程可以保护多个线程;
- 进程出现错误不会影响其他进程,但是一个线程出现错误,会影响同一进程下的所有线程。
线程的使用
线程的创建
一般使用std::thread
创建一个线程。std::thread
支持输入一个函数对象,及一些参数,类似于std::bind
,不过没有占位符。
最常见,最简单的是对输入一个匿名函数作为参数:
std::thread t1([]() {
std::cout << "Hello World" << std::endl;
});
t1.join();
结果如下:
需要注意的是,在使用多线程的时候,如果使用类似于std::cout << "Hello World" << std::endl;
的语句,容易造成输出的混乱。比如
std::thread t1([]() {
std::cout << "Hello World1" << std::endl;
});
std::thread t2([]() {
std::cout << "Hello World2" << std::endl;
});
t1.join();
t2.join();
以上代码,我们一般来说期望的输出是
但是,在一些情况下,它还会以以下的方法输出
造成这个的原因很简单,因为"Hello World"
和std::endl
的输出是分开的,所以他们之间可能被插入其他的输出。为了解决这个问题。一般会使用一个完整的字符串进行输出,但是C++在格式化这一方面做的比较差(C++20
的format
库看起来还不错),所以一般情况下会使用printf
输出。
线程的方法和属性
joinable()
判断线程是否可连接(可执行线程)的,有以下情况的,为不可连接的:- 构造时,
thread()
没有参数; - 该对象的线程已经被移动了;
- 该线程已经被
join
或detach
;
- 构造时,
get_id()
返回线程的ID;native_handle()
返回POSIX
标准的线程对象;join()
等待线程执行完成;detach()
分离线程,分离后对象不再拥有线程。该线程结束后,会自动回收内存。(并不会开启另一个进程);swap()
交换对象的线程。
std::jthread (C++20)
除了常用的std::thread
外,标准库还存在着另一个可以创建线程的类,std::jthread
。他们之间的差别比较明显的就是,std::jthread
会在解构的时候判断线程是否还在运行joinable
,如果还在运行则自动调用request_stop
和join
。
除此之外,std::jthread
还提供了一个内置的std::stop_token
。可以通过线程函数的第一个参数来获取(如果函数的第一个参数类型为std::stop_token
)。
可以通过get_stop_source
、get_stop_token
、request_stop
等方法来对其进行操作。
stop_token (C++20)
stop_token
类似于一个信号,告诉线程是否到了结束的时候。和stop_source
一起使用。stop_token
用来获取是否退出(读),而stop_source
用来请求推出(读写)。其方法:
request_stop
请求退出stop_requested
获取是否已经请求退出stop_possible
获取是否可以请求退出
样例:
void thread_func(std::stop_token token) {
int data = 0;
while (!token.stop_requested()) {
printf("%d\n", data);
data++;
std::this_thread::sleep_for(1s);
}
printf("Exit\n");
}
int main() {
std::jthread mythread(thread_func);
std::this_thread::sleep_for(4s);
return 0;
}
输出:
总结
本次讲述了线程创建的一些方法,可以看到相比较C语言而言,由于C++11提出的函数对象(普通函数、匿名函数,std::bind
的输出等)使得线程的创建更加的方便。
下一次将讲述线程之间的通信。在C++中,线程之间的通信方法和C语言提供的类似,不过是将其包装了一下。
Ref
[1] https://www.zhihu.com/question/25532384
博客原文:https://www.cnblogs.com/ink19/p/std_thread-1.html
std::thread线程详解(1)的更多相关文章
- std::thread线程库详解(2)
目录 目录 简介 最基本的锁 std::mutex 使用 方法和属性 递归锁 std::recursive_mutex 共享锁 std::shared_mutex (C++17) 带超时的锁 总结 简 ...
- Java线程创建形式 Thread构造详解 多线程中篇(五)
Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...
- 通用线程:POSIX 线程详解,第 3 部分 条件互斥量(pthread_cond_t)
使用条件变量提高效率 本文是 POSIX 线程三部曲系列的最后一部分,Daniel 将详细讨论如何使用条件变量.条件变量是 POSIX 线程结构,可以让您在遇到某些条件时“唤醒”线程.可以将它们看作是 ...
- Java基础-进程与线程之Thread类详解
Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...
- python线程详解
#线程状态 #线程同步(锁)#多线程的优势在于可以同时运行多个任务,至少感觉起来是这样,但是当线程需要共享数据时,可能存在数据不同步的问题. #threading模块#常用方法:'''threadin ...
- Thread.setDaemon详解
Thread.setDaemon详解 线程分为两种类型:用户线程和守护线程.通过Thread.setDaemon(false)设置为用户线程:通过Thread.setDaemon(true)设置为守护 ...
- 通用线程:POSIX 线程详解,第 3 部分
通用线程:POSIX 线程详解,第 3 部分 使用条件变量提高效率 Daniel Robbins, 总裁兼 CEO, Gentoo Technologies, Inc. 简介: 本文是 POSIX 线 ...
- POSIX 线程详解(经典必看)
http://www.cnblogs.com/sunminmin/p/4479952.html 总共三部分: 第一部分:POSIX 线程详解 ...
- java.lang.Thread类详解
java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...
随机推荐
- 2020.10.17 JZOJ 提高B组T2 导弹拦截
2020.10.17 JZOJ 提高B组T2 导弹拦截 题目 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统. 敌国的导弹形成了立体打击,每个导弹可以抽象成一个三维空间中的 ...
- JZOJ2020年8月10日提高组T3 玩诈欺的小杉
JZOJ2020年8月10日提高组T3 玩诈欺的小杉 题目 Description 是这样的,在小杉的面前有一个N行M列的棋盘,棋盘上有\(N*M\)个有黑白棋的棋子(一面为黑,一面为白),一开始都是 ...
- Codeforces Educational Round 94 (Rated for Div. 2)
昨晚算是不幸中的万幸了 A题问的是给2n-1个01串,让你构造出来一个n串使得从1开始每个长度为n的串都至少存在有一个相似的地方 这道题我一开始没什么想法,但是手动观察发现每次可以留出来的空挡间隔为1 ...
- RabbitMQ Go客户端教程5——topic
本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第五篇--topic. 这些教程涵盖了使用RabbitMQ创建消息传递 ...
- 老猿学5G扫盲贴:与用户和终端相关的名词UE、SUPI、GPSI、PEI
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 和4 ...
- js中的(function(){})()立即执行
( function(){-} )() 和 ( function (){-} () ) 是两种javascript立即执行函数的常见写法,要理解立即执行函数,需要先理解一些函数的基本概念. 函数声明. ...
- css3实现立体魔方效果
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- qtp学习入门
qtp的学习,初始入门是简单的,推荐田艳琴的<QTP从实践到精通>这边书,看过后,一周就可以入门,并能够自行编写脚本,但是想要进入更深一层,则需要更广阔的知识!这条路任重道远,你我共勉
- Springboot mini - Solon详解(一)- 快速入门
一.Springboot min -Solon 最近号称 Springboot mini 的 Solon框架,得空搞了一把,发觉Solon确实好用,小巧而快速.那Solon到底是什么,又是怎么好用呢? ...
- FHQ简要笔记
前言 原文写于 XJ 集训day2 2020.1.19. 现在想想那时候连模板都还没写,只是刚刚理解就在那里瞎yy--之前果然还是太幼稚了. 今天刷训练指南发现全是 Treap 和 Splay ,不想 ...