• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-05-07 10:38 Aet 隐藏边栏 |   抢沙发  9 
文章评分 6 次,平均分 5.0

介绍

每个C++进程都拥有至少一个线程,它是由C++在运行时启动的。该线程运行着main()函数。

我们自己的程序可以继续启动具有其他函数作为入口的线程。然后,这些线程连同初始线程一起,并发运行。

正如程序会在main()函数返回时退出那样,当指定的入口函数返回时,该线程就会退出。

启动线程

可以传给thread对象一个可调用对象,来启动线程

可调用对象

  • 函数
  • 函数指针
  • lambda表达式
  • bind()创建的对象
  • 重载了函数调用运算符的类

上述情况,所提供的函数对象将被复制到属于新创建的执行线程的存储器中,并从那里调用。

等待线程完成

可以通过join()来完成

join()的行为会清理所有与该线程相关联的存储器,会导致std::thread对象不再与已完成的线程相关联。

也就是意味着,一旦调用了join(),此std::thread对象不再是可连接的,joinable()将返回false

在异常环境下的等待

上述方法不好,比较啰嗦,容易将作用域弄乱

下面使用RAII(资源获取即初始化)的做法

  • 4
    • 对象g先被析构
  • 1
    • 在析构中先判断线程是否可结合
  • 2
    • 在析构中线程被结合,这样后面的do_some_thing_in_cur_thread()是否发生异常,线程都会被结合
  • 3
    • 拷贝构造和赋值运算符被禁用,避免thread_guard对象可能比它结合的线程的作用域的声明周期更长的情况

后台运行线程

可以通过detach()来完成

它会把线程丢在后台运行,我们没有直接的方法与之通信

如果一个线程成为分离的,获取一个引用它的std::thread对象是不可能的。所以它也不能再被结合。

分离的线程的所有权和控制权都交给了C++运行时库,以确保线程相关联的资源在线程退出后能够正确地回收。

按照UNIX的守护进程的概念,被分离的线程通常被称作为守护线程。

传参给线程

转移线程所有权

运行时选择线程数量

C++标准库中对此有帮助的特性是std::thread::hardware_concurrency().

这个函数返回一个对于给定程序执行时能够真正并发运行的线程数量的指示。

标识线程

线程标识符是std::thread::id类型的,并且有两种获取方式。

  • 线程的标识符可以通过从与之相关联的std::thread对象中通过调用get_id()成员函数来获得。
    • 如果std::thread对象没有相关联的执行线程,get_id()返回一个默认构造的std::thread::id对象,表示“没有线程”。
  • 当前线程的标识符,可以通过调用std::this_thread::get_id()获得
    • 定义在<thread>头文件中

另外,std::thread::id类型的对象可以自由地复制与比较:

  • 两个std::thread::id类型的对象相等,则它们代表着同一个线程
  • 两个std::thread::id类型的对象不相等,则它们代表不同线程或者其中一个代表着线程,另一个表示“没有线程”
  • 两个std::thread::id类型的对象都具有“没有线程”

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2023-09-16
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享