《线程管理:线程基本操作》

目录

  • 线程管理
    • 启动线程与(不)等待线程完成
    • 特殊情况下的等待(使用trycath或rall)
    • 后台运行线程

线程管理

启动线程与(不)等待线程完成

提供的函数对象被复制到新的线程的存储空间中,函数对象的执行和调用都在线程的内存空间中进行。

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

注意,如果传递的是一个临时变量,而不是一个命名变量,cpp编译器会将其解析为函数声明,而不是类型对象的定义。

当我们不等一个线程返回时,我们需要先将数据复制到线程中,这样就不会产生访问到已经销毁的变量的问题了。

就如下所示,函数已经返回,线程依旧能够访问到局部变量

struct func
{int& i;func(int& i_) : i(i_) {}void operator() (){for (unsigned j=0 ; j<1000000 ; ++j){// 1 潜在访问隐患:空引用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();
}
// 2 不等待线程结束
// 3 新线程可能还在运行

oops函数执行完成时,线程中的函数还在执行,还会访问已经销毁了的some_local_state变量,因为它持有的是该变量的指针。所以需要将数据复制到线程中,原始对象被销毁也不妨碍线程中变凉了。当然,使用访问局部变量的函数去创建线程不是很好。

此外,可以通过join()函数来确保线程在主函数完成前结束,可以确保局部变量在线程完成后才销毁。

注意,只能对一个线程使用一次join,一旦使用过join,thread对象就不能再次汇入。

特殊情况下的等待(使用trycath或rall)

对于一个未销毁的thread对象,如果想分离线程,在线程启动后直接使用detach()进行分离。如果想等待线程,就需要思考好join位置,也要考虑抛出异常给join带来的生命周期问题。

如下:使用了try/catch块确保线程退出后函数才结束

struct func;	//定义代码上面有
void f()
{int some_local_state = 0;func my_func(some_local_state);std::thread t(my_func);try{do_something_in_current_thread();}catch(...){t.join();throw;}t.join();
}

接下来介绍使用RALL等待线程完成

class thread_guard
{std::thread& t;
public:explicit thread_guard(std::thread& t_): t(t_) {}~thread_guard(){if(t.joinable())		//1t.join();			//2}thread_guard(thread_guard const&) = delete;		//3thread_guard& operator = (thread_guard const&) = delete;
};	
struct func;void f()
{int some_local_state = 0;func my_func(some_local_state);std::thread t(my_func);thread_guard g(t);do_something_in_current_thread();
}			//4

当线程执行到4,局部对象就要被逆序销毁了。所以,对象g第一个被销毁,线程在析构函数中,判断是可join的,随之执行join。所以即使do_something_in_current_thread函数跑出异常,这个销毁依旧会发生。

还有个需要注意的地方,拷贝构造函数和拷贝赋值操作做标记为 =delete,编译器不会自动生成。因为直接对对象进行拷贝或者赋值可能会丢失已经join的线程。

如果不想等待线程结束,可以分离线程,从而避免异常。不过这就打破了线程与std::thread对象联系。即使线程仍然在后台运行,detach操作也能确保std::terminate()在std::thread对象销毁时才调用。

后台运行线程

一个线程在后台运行,就不能与主线程直接交互,分离的线程也不能join,不过c++保证,当线程退出时,相关资源能够正确回收。

分离线程又称守护线程。在UNIX中,守护线程指的是没有任何显式接口,并在后台运行的线程。特点是长时间运行。

下面介绍一下分离线程的使用场景:

让一个文字处理应用同时编辑多个文档。每个文档窗口看起来完全独立,每个窗口也都有自己独立的菜单选项,但他们却运行在同一个应用实例中。一种内部处理方式是,让每个文档处理窗口拥有自己的线程。每个线程运行同样代码,并隔离不同窗口处理的数据。所以没打开一个文档就要启动一个新线程,因为是对独立文档进行操作,所以没有必要等待其他线程完成,可以让文档处理窗口运行在分离线程上。

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);		//1t.detach();									//2}else{process_user_input(cmd);}}}

用户选择打开一个新文档,需要启动一个新线程去打开新文档(如step1),并分离线程(如step2)。与当前线程做出的操作一样,新线程只不过是打开另一个文件而已。所以,edit_document函数可以复用,并通过传参的形式打开新的文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scala特质_Scala的特质

scala特质Scala特质 (Scala traits) Traits in Scala are like interfaces in Java. A trait can have fields and methods as members, these members can be abstract and non-abstract while creation of trait. Scala中的特性类似于Java中的接口 。 特征可以具有作为成员的…

优化PHP代码的40条建议(转)

优化PHP代码的40条建议 40 Tips for optimizing your php Code 原文地址&#xff1a;http://reinholdweber.com/?p3 英文版权归Reinhold Weber所有&#xff0c;中译文作者yangyang&#xff08;aka davidkoree&#xff09;。双语版可用于非商业传播&#xff0c;但须注明英文版作…

Iptables入门教程

转自&#xff1a;http://drops.wooyun.org/tips/1424 linux的包过滤功能&#xff0c;即linux防火墙&#xff0c;它由netfilter 和 iptables 两个组件组成。 netfilter 组件也称为内核空间&#xff0c;是内核的一部分&#xff0c;由一些信息包过滤表组成&#xff0c;这些表包含内…

《线程管理:传递参数、确定线程数量、线程标识》

参考《c Concurrency In Action 》第二章做的笔记 目录传递参数量产线程线程标识传递参数 thread构造函数的附加参数会拷贝至新线程的内存空间中&#xff0c;即使函数中的采纳数是引用类型&#xff0c;拷贝操作也会执行。如果我们期待传入一个引用&#xff0c;必须使用std::re…

手把手玩转win8开发系列课程(14)

这节的议程就是——添加appbar appbar是出现在哪儿了&#xff0c;出现在屏幕的底部。他能使用户能用手势或者使用鼠标操作程序。metro UI 重点是在主要的控件使用许多控件&#xff0c;使其用户使用win8电脑更加的方便。而appBar使其用户体验更好。在这节中&#xff0c;我将告诉…

No identities are available for signing 的解决办法

今天重新上传做好的app提交到app store&#xff0c;结果就出现标题上的错误。“No identities are available for signing”。 以后碰到这样的问题按照下面几个步骤来做&#xff1a; 进入Distribution -----下载发布证书 -----双击安装-----重启Xcode就能上传了 其他细节 如果再…

半连接反连接

半连接&反连接 1. 半连接 半连接返回左表中与右表至少匹配一次的数据行&#xff0c;通常体现为 EXISTS 或者 IN 子查询。左表驱动右表。只返回左表的数据&#xff0c;右表作为筛选条件。 可以用 EXISTS、 IN 或者 ANY 举例&#xff1a;表t1和表t2做半连接&#xff0c;t…

匿名方法和Lambda表达式

出于MVVM学习的需要&#xff0c;复习下匿名方法和Lambda表达式&#xff0c;因为之前用的也比较少&#xff0c;所以用的也不是很熟练&#xff0c;Baidu下相关的知识&#xff0c;写了这个Demo&#xff0c;目标是用简单的方法展示这个怎么用。 这里偏重的和LINQ中的Lambda表达式 …

烂橘子

Problem Statement: 问题陈述&#xff1a; Given a matrix of dimension r*c where each cell in the matrix can have values 0, 1 or 2 which has the following meaning: 给定尺寸r * C的矩阵&#xff0c;其中矩阵中的每个单元可以具有其具有以下含义的值0&#xff0c;1或2…

android junit 测试程序

http://blog.csdn.net/to_cm/article/details/5704783 Assert.assertEquals(2, t); 断言转载于:https://www.cnblogs.com/wjw334/p/3714120.html

MySQL 8.0.22执行器源码分析HashJoin —— BuildHashTable函数细节步骤

BuildHashTable函数细节步骤 该函数位置处于hash_join_iterator.cc 403 ~ 560行 step1&#xff1a;如果被驱动表迭代器没有更多的行数&#xff0c;更新m_state为EOR&#xff0c;然后返回false&#xff0c;表明创建hash表失败 if (!m_build_iterator_has_more_rows) {m_state…

《那些年啊,那些事——一个程序员的奋斗史》——125

距离离职交接的一个月时间还剩几天&#xff0c;本来应该是平淡无事的&#xff0c;却没想到最后还是波澜四起。昨天下班前&#xff0c;公司突然停了电。这本是件普通得不能再普通的事情&#xff0c;可没想到过了一会来电了&#xff0c;或许是波峰电压太大&#xff0c;或许是稳压…

python中的元类_Python中的元类

python中的元类Python元类 (Python metaclass) A metaclass is the class of a class. A class defines how an instance of a class i.e.; an object behaves whilst a metaclass defines how a class behaves. A class is an instance of a metaclass. 元类是类的类。 一个类…

MySQL 8.0.22执行器源码分析HashJoin —— 一些初始化函数的细节步骤

目录InitRowBuffer&#xff08;101行~126行&#xff09;InitProbeIterator&#xff08;142行~153行&#xff09;*HashJoinIterator* 的Init&#xff08;155行~240行&#xff09;InitializeChunkFiles&#xff08;364行~401行&#xff09;InitWritingToProbeRowSavingFile&#…

c语言的宏定义学习笔记

宏定义 在预处理之前&#xff0c;c预处理器会对代码进行翻译&#xff0c;譬如用blank替换注释&#xff0c;去掉多余的空格&#xff0c;删除末尾的\来拼接行等。 例如&#xff1a; int /*注释*/ x; 会被翻译成 int x; printf("this is a s\ entence."); 会被翻译成 pr…

摄氏温度转换华氏温度_什么是摄氏温度?

摄氏温度转换华氏温度摄氏温度 (Celsius) Celsius is a temperature measuring scale which as a SI unit derived from the seven base units stated and described by the International System of Units (SI). 摄氏温度是一种温度测量刻度&#xff0c;它是由国际单位制(SI)所…

别人的算法学习之路

http://www.cnblogs.com/figure9/p/3708351.html 我的算法学习之路 关于 严格来说&#xff0c;本文题目应该是我的数据结构和算法学习之路&#xff0c;但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法&#xff08;例如算法导论指的实际上是数据结构和算法导论&a…

git config命令使用第二篇——section操作,多个key值操作,使用正则

接上一篇&#xff0c;git config命令使用第一篇——介绍&#xff0c;基本操作&#xff0c;增删改查:http://blog.csdn.net/hutaoer06051/article/details/8275069 1. 删除一个section 命令参数 --remove-section 格式&#xff1a;git config [--local|--global|--system] --rem…

MySQL面试准备——64页pdf

本笔记为以前整理的零碎的关于Mysql的知识点&#xff0c;有深入源码的也有浅层的八股。已经被我整理成了一个pdf。 实习岗位正好也是和数据库内核有关的&#xff0c;之后应该还会更新。做个整理&#xff0c;方便秋招的时候快速回顾吧。 链接&#xff1a;链接 提取码&#xff1a…

python点图_Python | 点图

python点图The dot plot is a type of data representation in which each data-point in the figure is represented as a dot. Dot plot underlies discrete functions unlike a continuous function in a line plot. Each value could be correlated but cannot be connecte…