最新要闻
- 今日快讯:哪吒纯电GT跑车遭贬低 CEO回应:就喜欢看不惯又干不掉我的样子
- 快资讯丨歪风盛行:日本将严惩暗拍空姐行为 违者将判处5年以下监禁或26万
- 999元起 中兴远航40上架:紫光展锐T760、10W快充
- 今日要闻!花枝招展
- 世界头条:浙江宁波空中突发巨响 官方回应:超高速飞行产生的音爆
- 当前观察:中兴Axon Pad官宣:四等宽窄边 支持一触互联
- 前沿资讯!百度:目前文心一言无官方App!已起诉苹果公司
- 啥事不干年薪130万:科技公司为何愿意“养闲人”?
- 今日最新!马斯克回应特斯拉降价:很多人有需求但买不起 只有降价才能满足需求
- 环球观速讯丨男子路边违停被查!司机竟掏出“联合国机动车驾驶证”
- 全球即时看!“云溪学子看云溪 云腾溪涌产业新”云溪区举行首届工业研学活动
- IPX6级防水防刮:宏碁墨尔本背包169元抄底(三种款式)
- 焦点快播:博主发薅高铁商务座羊毛攻略 20元享超VIP服务网友效仿:12306回应怒赞
- 环球快消息!平台回应机票一分钟三次变价:实时价格变动正常
- 英雄之光|陈旧的记录本 是他牵挂群众最温暖的见证
- 世界即时看!你的工资不能低于这数!31省份最低工资公布:时薪达标没
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
C++ 并发编程实战 第二章 线程管控
第二章 线程管控
std::thread 简介
构造和析构函数
/// 默认构造/// 创建一个线程,什么也不做thread() noexcept;/// 带参构造/// 创建一个线程,以 A 为参数执行 F 函数template explicit thread(Fn&& F, Args&&... A);/// 拷贝构造(不可用)thread(thread& Other) noexcept = delete;/// 移动构造/// 移交线程的归属权thread(thread&& x) noexcept;/// 析构函数~thread();
常用成员函数
/// 等待线程结束并清理资源(会阻塞)void join();/// 返回线程是否可以执行 join() 成员函数bool joinable();/// 将线程与调用其的线程分离,彼此独立执行(此函数必须在线程创建时立即调用,/// 且调用此函数会使其不能被join)void detach();/// 获取线程idstd::thread::id get_id();/// 见移动构造函数/// 如果对象是 joinable 的,那么会调用 std::terminate() 结果程序thread& operator=(thread&& Other) noexcept;
使用线程类完成线程的基本管控
发起线程
- 线程通过构建std::thread对象而启动,该对象指明线程要运行的任务。
void do_some_work();std::thread my_thread(do_some_work);
- 对应复杂的任务,可以使用函数对象。
class background_task{public: void operator()() const{ do_something(); do_something_else(); }};background_task f;std::thread my_thread1(f);// 使用匿名函数对象// std::thread my_thread2(background_task());这样写会出错,// 编译器会解释成函数声明,返回值为 std::thread, 函数名为 my_thread2,// 函数参数为函数指针类型 background_task (*)(void), 因此改为如下两种方式:std::thread my_thread2((background_task()));// 采用新式的统一初始化语法(uniform initialization syntax,又名列表初始化)std::thread my_thread2{background_task()};
等待线程完成
一旦启动了线程,我们就需明确是要等待它结束(与之汇合 join()
),还是任由它独自运行(与之分离 detach()
)
【资料图】
std::thread my_thread1(f);// ...my_thread1.join();// 等待线程结束并清理资源
❗❗❗ 同一个线程的
.join()
方法不能被重复调用,否则程序会abort()
对 thread
封装——thread_guard
基于 RAII 原理,对 std::thread
进行封装
// std::thread 封装(基于RAII)class thread_guard{ thread& m_thread;public: explicit thread_guard(thread& t):m_thread(t){} ~thread_guard() { // 检查是否joinable是有必要的,重复 join() 会出错 if (m_thread.joinable()){ m_thread.join(); } } // C++11 "=delete" 标记,声明拷贝构造和复制赋值操作为被删除的函数 // 防止拷贝导致重复调用 join() thread_guard(thread_guard const&) = delete; thread_guard& operator=(thread_guard const&) = delete;};int main(){ thread t([] {cout << "hello" << endl; }); thread_guard g(t);}
这样线程,将随着类的析构,自动被回收。
线程后台运行
- 调用
std::thread
对象的成员函数detach()
,会令线程在后台运行,遂无法与之直接通信。 - 线程被分离,就无法等待它完结,也不可能获得与它关联的
std::thread
对象,因而无法汇合该线程。 - 分离的线程确实仍在后台运行,其归属权和控制权都转移给C++运行时库(runtime library,又名运行库),由此保证,一旦线程退出,与之关联的资源都会被正确回收。
- UNIX操作系统中,有些进程叫作守护进程(daemon process),它们在后台运行且没有对外的用户界面;沿袭这一概念,分离出去的线程常常被称为守护线程(daemon thread)
std::thread t(do_background_work);t.detach();assert(!t.joinable());// C++ 断言,表达式为假就输出诊断消息并调用abort()函数中止程序
向线程函数传递参数
void f(int i,std::string const& s);std::thread t(f,3,"hello");
- thread 执行带有引用类型参数的函数
int b = 10;// 必须使用 std::ref 指定参数按引用传递,否则参数默认以右值引用传递// 右值引用无法转换为引用类型参数thread t([](int& a) { cout << a << endl; }, ref(b));t.join();
- thread 执行类中的成员函数
class Person {public: void show(string const& name, unsigned int const& age) { cout << "name: " << name << endl; cout << "age: " << age << endl; }};int main(){ Person p; // 每个对象的成员函数都有一个默认的参数,就是该对象的指针(this 指针) // 因此,这里第一个参数要传入对象的地址 thread t(&Person::show, &p, "Tom", 22); t.join();}
- thread 执行的函数中,参数使用了移动构造
void process_big_object(std::unique_ptr);std::unique_ptr p(new big_object);p->prepare_data(42);std::thread t(process_big_object,std::move(p));// 必须使用 std::move() 将左值转换为右值
在C++标准库中,有几个类的归属权语义与 std::unique_ptr
一样,std::thread
类就是其中之一。
它们没有拷贝构造和复制赋值(=delete
),只能移动不能复制,保证了任意时刻对于唯一的资源,只有唯一的对象与其对应。
对于 std::thread
只允许将线程归属权从一个对象移动给另一个对象。
移交线程的归属权
/// 移动构造/// 移交线程的归属权thread(thread&& x) noexcept;
❗❗❗
只能从一个已关联执行线程的
thread
对象将线程归属权移交给还未关联任何执行线程的thread
对象。如果后者也关联了某个执行线程,那么操作会使程序abort()
因此重要原则是:只要std::thread对象正管控着一个线程,就不能简单地向它赋新值,否则该线程会因此被遗弃。
std::thread
支持移动操作的意义是,函数可以便捷地向外部转移线程的归属权
- 从函数内部返回
std::thread
对象
std::thread f(){ void some_function(); return std::thread(some_function);}std::thread g(){ void some_other_function(int); std::thread t(some_other_function,42); return t;}
- 线程归属权转移到函数内部
void f(std::thread t);void g(){ void some_function(); f(std::thread(some_function)); std::thread t(some_function); f(std::move(t));}
thread_guard
升级
- 使得可以直接使用封装好的类创建线程对象,并由类掌管。而不必现先在类外创建具名变量。
- 封装好的类对线程有唯一归属权,不必担心其他对象执行汇合或分离操作。
class soped_thread { thread m_thread;public: explicit soped_thread(thread t) : m_thread(move(t)){ if (!m_thread.joinable()) throw logic_error("No thread"); } ~soped_thread() { m_thread.join(); } soped_thread(soped_thread const&) = delete; soped_thread& operator=(soped_thread const&) = delete;};int main(){ soped_thread t{ thread([] { int i = 10; while (i--) { cout << i << endl; this_thread::sleep_for(chrono::seconds(2)); } })};}
使用示例
例1:thread 的基本使用
线程管控的自动化:若要为多个线程分别直接创建独立变量,还不如将它们集结成组,统一处理。
void do_work(unsigned id) { // 可以测试一下 printf 和 cout << id << endl;两种方式输出 // 使用 cout << id << endl; 输出id和输出endl的连续动作可能被其他线程打断。 printf("%d\n", id);}int main(){ vector threads; for (int i = 0; i < 10; i++){ threads.emplace_back(do_work, i); } for (auto& entry : threads) entry.join();}
例2:线程分离的应用场景
场景描述:
一个文字处理的应用程序
同时编辑多个文件,多个独立的顶层窗口,分别与正在编辑的文件逐一对应,窗口各有自己的选项单。
解决方案:使用多线程并行处理。
- 在同一应用程序的实例中运行。
- 相应的内部处理是,每个文件的编辑窗口都在各自线程内运行;每个线程运行的代码相同,而处理的数据有别,因为这些数据与各文件和对应窗口的属性关联。
- 打开一个新文件就需启动一个新线程。新线程只处理打开新文件的请求,并不牵涉等待其他线程的运行和结束。对其他线程而言,该文件由新线程负责,与它们无关。
综上,运行分离线程就成了首选方案。
void edit_document(std::string const& filename){ open_document_and_display_gui(filename); while(!done_editing()) { user_command cmd = get_user_input();// 获取用户输入命令 // 如果用户输入命令是打开新文件,就开启一个新线程,在新线程下打开文件 if(cmd.type == open_new_document) { std::string const new_name = get_filename_from_user(); // 开启新线程打开该文件 std::thread t(edit_document,new_name); t.detach();// 分离新线程 } else { // 执行用户命令 process_user_input(cmd); } }}
例3:thread 类的封装 joining_thread 类
曾经有一份C++17标准的备选提案,主张引入新的类joining_thread,它与std::thread类似,但只要其执行析构函数,线程即能自动汇合,这点与scoped_thread非常像。可惜C++标准委员会未能达成共识,结果C++17标准没有引入这个类,后来它改名为std::jthread,依然进入了C++20标准的议程(现已被正式纳入C++20标准)。除去这些,实际上joining_thread类的代码相对容易编写,代码清单2.7展示了一个可行的实现。
class joining_thread{std::thread m_thread;public:joining_thread() noexcept = default;templateexplicit joining_thread(Callable&& func, Args&& ... args): m_thread(std::forward(func), std::forward(args)...){}explicit joining_thread(std::thread t) noexcept: m_thread(std::move(t)){}joining_thread& operator=(joining_thread&& other) noexcept{if (joinable()) join();m_thread = std::move(other.m_thread);return *this;}joining_thread& operator=(std::thread other) noexcept{if (joinable()) join();m_thread = std::move(other);return *this;}~joining_thread() noexcept{if (joinable()) join();}void swap(joining_thread& other) noexcept{m_thread.swap(other.m_thread);}std::thread::id get_id() const noexcept {return m_thread.get_id();}bool joinable() const noexcept{return m_thread.joinable();}void join(){ m_thread.join(); }void detach() { m_thread.detach(); }std::thread& as_thread() noexcept { return m_thread; }const std::thread& as_thread() const noexcept{return m_thread;}};
关键词:
-
全球微速讯:gazebo小车模型(附带仿真环境)
gazebo小车模型(附带仿真环境)参考链接1、(https: blog csdn net qq_43406338 article details 109600827?ops_request_m
来源: 全球观点:Python 元编程
C++ 并发编程实战 第二章 线程管控
全球微速讯:gazebo小车模型(附带仿真环境)
今日快讯:哪吒纯电GT跑车遭贬低 CEO回应:就喜欢看不惯又干不掉我的样子
快资讯丨歪风盛行:日本将严惩暗拍空姐行为 违者将判处5年以下监禁或26万
999元起 中兴远航40上架:紫光展锐T760、10W快充
今日要闻!花枝招展
世界头条:浙江宁波空中突发巨响 官方回应:超高速飞行产生的音爆
当前观察:中兴Axon Pad官宣:四等宽窄边 支持一触互联
前沿资讯!百度:目前文心一言无官方App!已起诉苹果公司
世界百事通!海南航空恢复伦敦至长沙直航航线
啥事不干年薪130万:科技公司为何愿意“养闲人”?
今日最新!马斯克回应特斯拉降价:很多人有需求但买不起 只有降价才能满足需求
环球观速讯丨男子路边违停被查!司机竟掏出“联合国机动车驾驶证”
全球即时看!“云溪学子看云溪 云腾溪涌产业新”云溪区举行首届工业研学活动
环球观热点:《系列一》-- 4、xml配置文件解析之[默认]命名空间[标签]的解析
天天热推荐:面试题百日百刷-HBase中HTable API有没有线程安全问题,在程序是单例还是多例?
IPX6级防水防刮:宏碁墨尔本背包169元抄底(三种款式)
焦点快播:博主发薅高铁商务座羊毛攻略 20元享超VIP服务网友效仿:12306回应怒赞
环球快消息!平台回应机票一分钟三次变价:实时价格变动正常
英雄之光|陈旧的记录本 是他牵挂群众最温暖的见证
世界即时看!你的工资不能低于这数!31省份最低工资公布:时薪达标没
世界最资讯丨山东推出399元高铁环游套票:有效期5天、全省免费换乘
每日热议!DIY万能钥匙!主板检测灯你不得不懂
【焦点热闻】09款奥迪A4L标准型改装泪眼/导航作业
最新资讯:Docker-compose 到 Kubernetes 的迁移工具!
世界速看:全新深红配色亮相!iPhone 15 Pro超高清外观渲染图首曝:钛金属边框、Type-C接口
世界资讯:诈骗网红梅尼耶的MCN游良文化被申请破产:小刚学长等多位网红受骗
焦点速读:Java性能权威指南(第2版)读后总结与感想
动态:大学招聘体育老师 要求得过奥运冠军引热议:官方回应专业技能很重要
复星旅文2022年收入137.78亿元 徐晓亮:要尽快追回过去三年失去的业绩
【天天报资讯】K8S圣经12:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
回顾、信号、flask-script、sqlalchemy介绍和快速使用、创建操作数据表
今日快看!ASP.NET Core MVC 从入门到精通之初窥门径
女主不够性感吗?《生化危机4重制版》发售两周狂卖超400万份:Steam好评如潮
Intel中国特供i5-13490F/i7-13790F闪电降价:性价比更神了!
天天看热讯:男人多次失恋后和娃娃订婚 还“生”了三个孩子
当年找抖音赔30亿的腾讯视频 这会儿怎么来世纪大和解了?
电视接口盘点 HDMI 2.1真的是刚需吗?
天天观点:罪恶都市任务攻略_侠盗飞车罪恶都市任务做完了怎么办
环球短讯!HRB500钢筋符号_HRB500的钢筋符号是什么 属于几级钢筋
热头条丨【调试】ftrace(三)trace-cmd和kernelshark
全球观天下!集成Unity3D到iOS应用程序中
环球视点!OpenCV获取相机旋转矩阵和平移矩阵
海信电视精简系统
【全球聚看点】试验设计课程作业
比亚迪海豹、长安深蓝SL03获央视第三届《中国汽车风云盛典》评委会大奖
诈骗网红梅尼耶的MCN被申请破产引热议 多位女网红等都受害:网友吐槽行业乱
世界即时看!女子开宝马占用商场特斯拉专用车位 被特斯拉怒堵2天
世界速递!2023.4.7【模板】快速沃尔什变换FWT
今日报丨面试题百日百刷-HBase HRegionServer宕机如何处理
第135篇:Three.js基础入门
每日消息!交易商协会评估更新定向债务融资工具专项机构投资人名单
美国3月非农就业人口增幅降至23.6万 失业率为3.5%
热文:构造柱的作用是什么_构造柱的作用
焦点热讯:网友称余额宝页面显示乱码 支付宝回应:正在修复 不影响资金安全
《龙马精神》电影中真打实摔 成龙:我69岁动作比你还快
热点!说十个需要送老婆礼物的节日
焦点观察:火热出炉 秘汁全鸡的数字新“味”
大阳睿能全新动力首款车型H12下线:电机1700W 续航150公里
249元 小米米家自动真空封口机发布:-70KPa大吸力
全球快资讯丨世界各地小孩的玩具对比:不止文化与财富的差距
当前动态:马斯克开源推特算法反被指责:隐藏重要细节、与承诺不符
【当前独家】《王者荣耀》S31赛季4月13日上线 新英雄姬小满来了
深圳开放大学优秀学生李德炎:保持学习状态,争做行业模范
天天快看点丨自动旋转ROS小车(rviz+urdf+xacro)(附加python操作键盘控制小车运动)
每日资讯:java -- Math、BigInteger、BigDecimal类和基本类型的包装类、正则表达式
【快播报】黑田东彦“卸任”言论释放宽松信号 日债收益率曲线平坦化下移
速递!定价全球最低!国产科幻FPS《边境》国区售价68元起
天天观热点:孟羽童已不是董明珠秘书引热议 本人回应:很享受格力市场营销工作
今日看点:米粉换上Redmi Note 12 Turbo:陪伴他5年的小米6正式退役
天天即时看!网友看电影觉得难看成功退一半费用 影城:散场20分钟内可办理
电动自行车调速器网上公开售卖!专家:私改限速或引发燃爆事故
环球资讯:ps 备忘清单_开发速查表分享
天天观天下!王者更新:祈愿夺宝重启,520传说天幕返场,5英雄喜提新衣
焦点速读:离谱!观致汽车要倒台 车主也被拉下水:被厂商告了
全球气象预报大模型风乌发布:有效预报时间首破10天
事关“刹车失灵”争议核心数据 本田中国召回超20万辆雅阁
长城财报漂亮 是因为新能源汽车卖得不漂亮
全球新资讯:仅1999元!铁威马F4-423(4G)四盘位NAS开启预售:双2.5G网口
全球速读:大美游轮2022年亏损2511.24万同比亏损增加 游轮运营业务毛利减少
Privilege Escalation 权限提升
即时焦点: 如何处理Xcode上传IPA文件后无法在后台架构版本中显示的问题?
当前要闻:易基因:群体分析揭示了DNA甲基化在番茄驯化和代谢多样性中的作用|组学研究
记录-VueJs中如何使用Teleport组件
Springfox与SpringDoc——swagger如何选择(SpringDoc入门)
澳大利亚一飞机掉入印度洋:全员坠海 未有伤亡
世界速递!比亚迪大疆达成合作!全新海狮将用上高级辅助驾驶技术:纯视觉走天下
每日消息!希捷推出星球大战版SSD:三款RGB光剑任选
资讯推荐:一图看懂!小米/红米多款热门机型官方降价:小米12S/13全系有活动
环球新动态:用两年就卡?3分钟学会选电视硬件
当前播报:申城交警多措并举加强高速公路和城市快速路事故预防工作
世界头条:用 Go 剑指 Offer 17. 打印从1到最大的n位数
【天天时快讯】获取Python函数信息的方法
世界信息:GPT对SaaS领域有什么影响?
全球新资讯:什么是 Java 字节码?采用字节码的好处是什么?
【天天聚看点】ubuntu离线安装tcpdump
因债券承销尽调不充分等问题 民生证券被上交所出具书面警示
每日视讯:最新确认:小米13 Ultra用上了USB 3.X接口
《流浪地球2》4月14日网络首播!导演郭帆:修改了一百多个视效镜头