管理线程
Posted chenying66
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了管理线程相关的知识,希望对你有一定的参考价值。
-
启动线程
-
与许多C++标准库相似,std::thread可以与任何可调用callable类型一同工作,所以可以将一个带有函数调用操作符的类的实例传递给std::thread的构造函数来进行代替。此时,所提供的函数对象被赋值到属于新创建的执行线程的存储器中,并从那里被调用。
-
但是如果直接传递一个临时的且未命名的变量是,其语法就变成了函数声明,去声明函数my_thread,它接受单个参数,并返回std::thread对象,而不是启动一个新的线程,此时的解决方案有三种
a. 使用额外的括号来避免其解释为函数声明 std::thread my_thread((background_task()));
b. 使用大括号来统一初始化语法 std::thread my_threadbackground_task();
c. 使用lambda表达式 -
一旦开始了线程,就必须显式的决定是要等待它完成还是让它自行运行。注意,允许对局部变量的指针或引用持续到函数推出之后绝不是一个好主意。
-
显式的决定有
a. detach():不再等待新线程
b. join():确保在函数退出前,新线程执行完毕。但是,此时就意味着在独立的线程上运行函数是没意义的,因为第一个线程在此期间将做不了任何有用的事情。调用join的行为也会清理所有与该线程相关联的存储器,即新的线程对象不再与现已完成的线程相关联,也不与任何线程相关联。
1. 判断一个线程是否已经被join过,只需使用t.jointable()函数,因为一旦调用了join,此std::thread对象不再是可连接的,并且joinable()将返回false。一定要注意,对于一个给定的执行线程join只能被调用一次,所以如果线程已经被结合了,就不能再对这个线程调用join函数了 -
如果显式决定使用detach,那么线程启动后可以立即调用detach。但是如果使用join,需要仔细的选择在代码的那个位置调用join。这是因为,若在线程开启之后但是调用join之前引发一场,那么对join的调用就容易被跳过
-
为了避免应用程序在引发异常的时候被终止,解决的方案有
a. 使用try-catch块,即使异常被catch捕获时也需要调用join,来保证无论函数时正常退出还是异常中断时,局部状态的线程在函数退出前结束
b. 使用标准的资源获取即初始化(RAII),并提供一个类,在它的析构函数中进行join -
使用detach以后,会把线程丢给后台运行,此时这个线程的所有权和控制权被转交给C++运行时库,以确保与线程项关联的资源在线程退出后能够被正确的回收。被detach的线程也不在能够被结合,std::thread对象不再与执行的实际线程相关联,同时也不能够被加入
-
给thread传递参数,只需要简单的将额外的参数传递给std::thread构造函数。但是这里要注意,如果传递的是对象或者传递的是引用的两种情况
a. 传递的是对象,如std::string,那么字符串自勉之尽在新线程的上下文中才会作为char const*传递,并转换为std::string,但是如果直接传递这个“helloworld”且使用detach的话,那么很有可能在新线程上被转换为std::string之前就退出函数,从而导致未定义行为。解决方案:在将缓冲传递给std::thread的构造函数之前转化为std::string,即使用std::string(buffer)
b. 传递的是参数的引用,那么要注意,由于std::thread的constructor会无视函数所期望的类型,并且盲目的复制所提供的值,那么这就将导致原先想对原始data值进行的修改会被自动舍弃。解决方案:使用std::ref来包装确实需要被引用的参数。std::ref(data) -
移动构造函数和移动赋值运算符允许一个对象的所有权在std::unique_ptr实例之间进行转移。对于std::thread而言,其实例也是可移动的,即使他们是不可复制的。使用std::move即可以对线程完成所有权的转移。注意,在原对象是临时的场合,这种移动是自动的,但在源是一个命名值的地方,此转移必须直接通过std::move来请求。
-
线程迈向自动管理的一步:将std::thread对象放到std::vector当中,std::for_each(thread.begin(), threads.end(), std::mem_fn(&std::thread::join));可以轮流在每个线程上调用join函数
-
muduo的学习路径:https://baozh.github.io/2015-11/muduo-source-code-step-by-step/
-
mudua源码解析:https://zhuanlan.zhihu.com/p/149699816
-
muduo源码地址:https://github.com/chenshuo/muduo
以上是关于管理线程的主要内容,如果未能解决你的问题,请参考以下文章