C++并发:线程管控

ops/2025/1/1 14:02:04/

1 线程基本管控

每个C++程序都含有至少一个线程,即运行main()的线程,它由C++运行时系统启动。随后程序可以发起更多线程,它们以别的函数作为入口。这些新线程连同起始线程并发运行。当main()返回时,程序就会退出;同样,当入口函数返回时,对应的线程随之终结。如果借std::thread对象管控线程,即可选择等他结束。

1.1 发起线程

线程通过构造std::thread对象而启动,该对象指明线程要运行的任务。

void do_some_work();
std::thread myThread(do_some_work);

任何可调用类型都适用于std::thread。所以,作为代替,可以设计一个带有函数调用操作符的类(应当是下面的operator)

class background_task
{
public:void operator() () const{do_something();do_something_else();}
};background_task f;
std::thread my_thread(f);

f被复制到属于新线程的存储空间中,在那里被调用,由新线程执行。

1.1.1 与函数声明进行区分

如果传入std::thread的是临时变量,不是具名变量,那么调用构造函数的语法有可能与函数声明相同。这种情况,编译器会将其解释成函数声明。

声明为函数:函数名为my_thread,只接收一个参数,返回std::thread对象
std::thread my_thread(background_task());可以通过多用一对圆括号或使用新式的统一初始化语法
std::thread my_thread((background_task()));
std::thread my_thread{background_task()};还可以使用lambda表达式
std::thread my_thread([]{do_something();do_something_else();
});

在启动线程后,需要明确是要等待他结束(也就是汇合)还是任由他独立运行(也就是分离)。如果等到std::thread销毁的时候还没有决定好,那么std::thread的析构函数将调用std::terminate()终止整个程序。

如果选择了分离,且分离时新线程还未运行结束,那将继续运行,甚至在std::thread对象销毁很久之后依然运行,它只有最终从线程函数返回时才会结束运行。

假设程序不等待线程结束,那么在线程运行结束前,我们要保证它所访问的外部数据始终正确,有效。由于使用多线程,所以我们可能会经常面临对象生存期的问题。比如下面的案例:

struct func
{int& i;func(int& i_):i(i_){}void operator() (){for (unsigned j=0; j<1000000; ++j) {do_something(i);    隐患:可能访问悬空引用}}
};void oops()
{int some_local_state=0;func my_func(some_local_state);std::thread my_thread(my_func);my_thread.detach();        不等待新线程结束新线程可能仍运行,而主线程的函数却已经结束
}


http://www.ppmy.cn/ops/146057.html

相关文章

B树B+树

#include <stdio.h> #include <stdlib.h>// 定义 B 树的最小度数&#xff08;每个节点至少有 t 个孩子&#xff0c;最多有 2t - 1 个键值&#xff09; #define T 3// B 树节点结构 typedef struct BTreeNode {int *keys; // 存储键值的数组int t; …

DOM解析:深入理解文档对象模型

DOM解析&#xff1a;深入理解文档对象模型 1. 引言 文档对象模型&#xff08;DOM&#xff0c;Document Object Model&#xff09;是HTML和XML文档的编程接口&#xff0c;它定义了文档的逻辑结构以及访问和操作文档的方式。DOM解析是将HTML或XML文档转换成DOM树的过程&#xf…

【java-数据结构篇】揭秘 Java LinkedList:链表数据结构的 Java 实现原理与核心概念

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 1. Java LinkedList 基础 1.1 LinkedList 简介 1.2 LinkedList 的实现原理 1.3 LinkedList 与 ArrayList 的区别 2. 链表基础 2.1 链…

Java编程规约 :OOP 规约

文章目录 引言I OOP规约【强制】【推荐】II 知识扩展:库的分类:(一方、二方、三方库)选择定义III 术语npe异常引言 I OOP规约 【强制】 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。禁止在 POJO 类中,同时存在对应属性 xxx 的 isXxx() 和…

Wireshark时间设置介绍:时间格式、时间参考和时间平移

简述 Wireshark是一个广泛使用的网络协议分析工具&#xff0c;它能够捕获并分析通过网络传输的各种数据包。在进行网络分析时&#xff0c;时间信息是非常关键的&#xff0c;它能够帮助我们了解数据包的流动和事件发生的顺序。Wireshark提供了多种配置选项&#xff0c;以便用户…

Python|Pyppeteer实现自动化获取reCaptcha验证码图片以及提示词(29)

前言 本文是该专栏的第29篇,结合优质项目案例持续分享Pyppeteer的干货知识,记得关注。 本文,是笔者推出“自动化破解reCaptcha验证码系列”的第二篇,对通过自动化解决“reCaptcha验证码”感兴趣的同学,千万别错过。 文章《Python|Pyppeteer实现全自动化触发reCaptcha验证…

服务器时间不同步

问题 每次设置完时间之后&#xff0c;过一段时间服务器的时间就会变慢。 date相关命令 date # 查询当前时间(日期及时间&#xff0c;格式为&#xff1a;周几 月 日 时:分:秒 时区 年) Tue Dec 24 11:53:14 CST 2024date "%Y-%m-%d %H:%M:%S" # 使用和格式字符串…

目标检测中的正负样本是什么,是如何起作用的?

1、正负样本的定义 1.1、正样本 正样本是指那些与真实目标&#xff08;Ground Truth, GT&#xff09;有很高关联性的样本&#xff0c;其作用是让模型学习目标的位置和类别特征。举个例子&#xff1a; Anchor-based中&#xff0c;如果一个候选框&#xff08;Anchor&#xff09;与…