std::thread线程详解(1)
2021-01-01 21:12
155 查看
目录
简介
本文主要介绍了标准库中的线程部分。线程是目前多核编程里面最重要的一部分。
与进程进程相比,其所需的资源更少,线程之间沟通的方法更多; 他们之间的区别可以比较简明用以下几点概括[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的输出是分开的,所以他们之间可能被插入其 ad8 他的输出。为了解决这个问题。一般会使用一个完整的字符串进行输出,但是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_ ad0 func); std::this_thread::sleep_for(4s); return 0; }
输出:
总结
本次讲述了线程创建的一些方法,可以看到相比较C语言而言,由于C++11提出的函数对象(普通函数、匿名函数,
std::bind的输出等)使得线程的创建更加的方便。
下一次将讲述线程之间的通信。在C++中,线程之间的通信方法和C语言提供的类似,不过是将其包装了一下。
Ref
相关文章推荐
- Java知多少(58)线程Runnable接口和Thread类详解
- C++11 并发指南二(std::thread 详解)
- innoDB 储存引擎 IO THread 后台线程 innodb_read_io_threads 和 innodb_write_io_threads 两个参数详解记录
- 线程概念详解(Thread)
- C++11 并发指南二(std::thread 详解)
- Thread线程相关方法详解
- 线程类Thread详解和线程的几种状态,守护线程
- Thread详解4:线程的优先级
- 深入多线程之:解析线程的交会(Thread Rendezvous)详解
- C++11 并发指南------std::thread 详解
- Thread(线程)详解2—多线程同步和线程池
- 【Boost】boost库中thread多线程详解11——线程的休眠和中断
- C++11 并发指南二(std::thread 详解)
- c++11中关于std::thread的join的详解
- Java Thread(线程)案例详解sleep和wait的区别
- java之Thread线程相关yield()、sleep()、wait()、join()、run和start区别详解
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
- MFC中CreatThread()创建线程使用详解
- Java并发编程:(2)线程状态和Thread类详解
- 【Boost】boost库中thread多线程详解12——线程的分离与非分离