目录

简介

本文主要介绍了标准库中的线程部分。线程是目前多核编程里面最重要的一部分。

与进程进程相比,其所需的资源更少,线程之间沟通的方法更多; 他们之间的区别可以比较简明用以下几点概括[1]:

  1. 进程是资源分配的最小单位,线程是CPU调度的最小单位;也就是说进程之间的资源是相互隔离,而线程之间的是可以相互访问的。
  2. 线程的存在依赖于进程,一个进程可以保护多个线程;
  3. 进程出现错误不会影响其他进程,但是一个线程出现错误,会影响同一进程下的所有线程。

线程的使用

线程的创建

一般使用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++20format库看起来还不错),所以一般情况下会使用printf输出。

线程的方法和属性

  1. joinable()判断线程是否可连接(可执行线程)的,有以下情况的,为不可连接的:

    1. 构造时,thread()没有参数;
    2. 该对象的线程已经被移动了;
    3. 该线程已经被joindetach
  2. get_id() 返回线程的ID;

  3. native_handle() 返回POSIX标准的线程对象;

  4. join() 等待线程执行完成;

  5. detach() 分离线程,分离后对象不再拥有线程。该线程结束后,会自动回收内存。(并不会开启另一个进程);

  6. swap() 交换对象的线程。

std::jthread (C++20)

除了常用的std::thread外,标准库还存在着另一个可以创建线程的类,std::jthread。他们之间的差别比较明显的就是,std::jthread会在解构的时候判断线程是否还在运行joinable,如果还在运行则自动调用request_stopjoin

除此之外,std::jthread还提供了一个内置的std::stop_token。可以通过线程函数的第一个参数来获取(如果函数的第一个参数类型为std::stop_token)。

可以通过get_stop_sourceget_stop_tokenrequest_stop等方法来对其进行操作。

stop_token (C++20)

stop_token类似于一个信号,告诉线程是否到了结束的时候。和stop_source一起使用。stop_token用来获取是否退出(读),而stop_source用来请求推出(读写)。其方法:

  1. request_stop 请求退出

  2. stop_requested 获取是否已经请求退出

  3. 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)的更多相关文章

  1. std::thread线程库详解(2)

    目录 目录 简介 最基本的锁 std::mutex 使用 方法和属性 递归锁 std::recursive_mutex 共享锁 std::shared_mutex (C++17) 带超时的锁 总结 简 ...

  2. Java线程创建形式 Thread构造详解 多线程中篇(五)

    Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...

  3. 通用线程:POSIX 线程详解,第 3 部分 条件互斥量(pthread_cond_t)

    使用条件变量提高效率 本文是 POSIX 线程三部曲系列的最后一部分,Daniel 将详细讨论如何使用条件变量.条件变量是 POSIX 线程结构,可以让您在遇到某些条件时“唤醒”线程.可以将它们看作是 ...

  4. Java基础-进程与线程之Thread类详解

    Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...

  5. python线程详解

    #线程状态 #线程同步(锁)#多线程的优势在于可以同时运行多个任务,至少感觉起来是这样,但是当线程需要共享数据时,可能存在数据不同步的问题. #threading模块#常用方法:'''threadin ...

  6. Thread.setDaemon详解

    Thread.setDaemon详解 线程分为两种类型:用户线程和守护线程.通过Thread.setDaemon(false)设置为用户线程:通过Thread.setDaemon(true)设置为守护 ...

  7. 通用线程:POSIX 线程详解,第 3 部分

    通用线程:POSIX 线程详解,第 3 部分 使用条件变量提高效率 Daniel Robbins, 总裁兼 CEO, Gentoo Technologies, Inc. 简介: 本文是 POSIX 线 ...

  8. POSIX 线程详解(经典必看)

    http://www.cnblogs.com/sunminmin/p/4479952.html 总共三部分: 第一部分:POSIX 线程详解                               ...

  9. java.lang.Thread类详解

    java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...

随机推荐

  1. (十八)面向流水线的设计:CPU的一心多用

    一.单指令周期       由前可知,一条CPU指令的执行有三个步骤:指令读取.指令译码.指令执行.由于这个过程受CPU时钟的控制,如果我们将这个过程安排在一个CPU时钟周期内执行,这种设计思路就叫单 ...

  2. 老猿学5G:融合计费场景的离线计费会话的Nchf_OfflineOnlyCharging_Create创建操作

    ☞ ░ 前往老猿Python博文目录 ░ 一.Nchf_OfflineOnlyCharging_Create消息交互流程 Nchf_OfflineOnlyCharging_Create服务化操作请求是 ...

  3. 老猿学5G扫盲贴:中国移动的5G计费架构解读

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.引言 在<老猿学5G扫盲贴:3GPP中的 ...

  4. 第9.4节 Python中用readline读取二进制文件方式打开文件

    在<第9.3节 Python的文件内容读取:readline>中介绍了使用readline读取文件的处理,readline除了使用文本文件方式打开文件读外,也可以读取二进制方式打开的文件, ...

  5. PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox增加自定义按钮的方法

    在Qt Designer中可以预先定义标准按钮,相关支持的标准按钮请见<PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的StandardButton ...

  6. PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象的animated属性

    animated属性用于设置在操作可浮动部件和工具栏时是否设置动画. 当一个可浮动部件或工具栏被拖到主窗口上时,主窗口将调整其内容,以显示浮动部件或工具栏应该放置的位置.设置此属性后主窗口将使用平滑动 ...

  7. sklearn决策树应用及可视化

    from sklearn import datasets from sklearn.tree import DecisionTreeClassifier 1.载入iris数据集(from sklear ...

  8. 第 2 篇Scrum 冲刺博客

    每天举行会议 会议照片: 昨天已完成的工作与今天计划完成的工作及工作中遇到的困难: 成员姓名 昨天完成工作 今天计划完成的工作 工作中遇到的困难 蔡双浩 完成修改个人信息剩余部分 了解任务,并做相关学 ...

  9. 微信小程序中使用text-indent实现首行缩进

    问题由来:在小程序中使用text标签包裹了一段话,要做一个首行缩进的效果,但是不起效果 . 解决方法:使用view标签代替text,使用text-indent:2em即可解决.

  10. linux文件实时同步

    参考博客:https://www.cnblogs.com/MacoLee/p/5633650.html 一.文件同步很简单 服务端:被动的接收传输过来的数据 客户端:主动提供数据给服务端 安装思路:服 ...