原 总结 C++11 thread 

概览

从C++11开始提供了线程的支持,终于可以方便的编写跨平台的线程代码了。除了std::thread类,还提供了许多其它便利同步的机制,本篇总结是C++11学习笔记系列的首篇总结。

std::thread

std::thread定义在<thread>中,提供了方便的创建线程的功能。

类定义

  1. class thread 

  2. { 

  3. public: 

  4. thread() noexcept; 

  5. thread( thread&& other ) noexcept; 

  6. template< class Function, class... Args > 

  7. explicit thread( Function&& f, Args&&... args ); 

  8. thread(const thread&) = delete; 

  9. ~thread(); 

  10. thread& operator=( thread&& other ) noexcept; 

  11. bool joinable() const noexcept; 

  12. std::thread::id get_id() const noexcept; 

  13. native_handle_type native_handle(); 

  14. void join(); 

  15. void detach(); 

  16. void swap( thread& other ) noexcept; 

  17. static unsigned int hardware_concurrency() noexcept; 

  18. }; 

从定义中我们可以得知:

各个成员函数的简单介绍

例子

因为thread类比较简单,我们通过几个例子来学习。

  • 支持移动语义,但不支持拷贝语义
  1. #include <thread> 

  2. void some_function() {} 

  3. void some_other_function() {} 

  4. int main() 

  5. { 

  6. std::thread t1(some_function); // 构造一个thread对象t1 

  7. std::thread t2 = std::move(t1); // 把t1 move给另外一个thread对象t2,t1不再管理之前的线程了。 

  8. // 这句不需要std::move(),从临时变量进行移动是自动和隐式的。调用的是operator=(std::thread&&) 

  9. t1 = std::thread(some_other_function); 

  10. std::thread t3; 

  11. t3 = std::move(t2); // 把t2 move给t3 

  12. // 把t3 move给t1,非法。因为`t1`已经有了一个相关的线程,会调用`std::terminate()`来终止程序。 

  13. t1 = std::move(t3); 

  14. } 

  • 通过调用join()成员函数来等待线程结束
  1. #include <iostream> 

  2. #include <thread> 

  3. #include <chrono> 


  4. void foo()  

  5. { 

  6. std::this_thread::sleep_for(std::chrono::seconds(1)); 

  7. } 


  8. int main() 

  9. { 

  10. std::cout << "starting first helper...\n"; 

  11. std::thread helper1(foo); 

  12. helper1.join(); 

  13. } 

  • 传递参数给线程函数
  1. void f(int i, std::string const& s); 

  2. std::thread t(f, 3 "hello"); 

注意:参数会以默认的方式被复制到内部存储空间,直到使用的时候才会转成对应的类型。

下面的例子有问题吗?有什么问题?

  1. void f(int i, std::string const& s); 

  2. void oops(int some_param) 

  3. { 

  4. char buffer[1024]; 

  5. sprintf(buffer, "%i", some_param); 

  6. std::thread t(f, 3, buffer); 

  7. t.detach(); 

  8. } 

局部变量buffer的指针会被传递给新线程,如果oops()在buffer被转换成string之前退出,那么会导致未定义的行为。解决之道是在构造std::thread的时候传递string变量。std::thread t(f, 3, std::string(buffer));

可以使用std::ref()来显示表明要传递引用,就像std::bind()那样。

  1. std::thread t(update_data_for_widget, w, std::ref(data)); 

  • 使用类的成员函数作为线程参数
  1. #include <thread> 

  2. #include <string> 

  3. class CRunner 

  4. { 

  5. public: 

  6. void run0(){} 

  7. void run1(int a) {} 

  8. void run2(int a, int b) const {} 

  9. int run3(int a, char b, const std::string& c) {return 0;} 

  10. int run4(int& a, double b, float c, char d) { ++a; return 0; } 

  11. static void run_static(int a) {} 

  12. }; 


  13. int main() 

  14. { 

  15. CRunner runner; 

  16. int a = 0; 

  17. // 使用std::mem_fun,需要传指针 

  18. std::thread t0(std::mem_fun(&CRunner::run0), &runner); 

  19. // 使用std::mem_fun_ref,可以传引用或副本 

  20. std::thread t1(std::mem_fun_ref(&CRunner::run1), std::ref(runner), 1); 

  21. // std::thread t1(std::mem_fun_ref(&CRunner::run1), runner, 1); 


  22. // 使用std::mem_fn,std::mem_fn支持多于一个参数的函数,std::mem_fun不支持。 

  23. std::thread t2(std::mem_fn(&CRunner::run2), std::ref(runner), 1, 2); 

  24. // 使用std::bind + std::mem_fn 

  25. std::thread t3(std::bind(std::mem_fn(&CRunner::run3), &runner, 1, 2, "data"));  

  26. // 使用std::mem_fn,注意std::ref的用法,如果不用std::ref行不行? 

  27. std::thread t4(std::mem_fn(&CRunner::run4), &runner, std::ref(a), 2.2, 3.3f, 'd');  

  28. // 使用类的静态函数 

  29. std::thread t5(&CRunner::run_static, 1); 


  30. t0.join(); 

  31. t1.join(); 

  32. t2.join(); 

  33. t3.join(); 

  34. t4.join(); 

  35. t5.join(); 

  36. } 

注:

更多

虽然在之前的例子中的函数有返回值,但是我们却不能获得,想获得返回值我们需要使用std::future,关于std::future的总结,后续会慢慢补充,敬请期待。

参考资料

[原]C++新标准之std::thread的更多相关文章

  1. [原]C++新标准之std::chrono::duration

    原 总结 C++11 chrono duration ratio  概览 std::chrono::duration 描述 类定义 duration_cast()分析 预定义的duration 示例代 ...

  2. [原]C++新标准之std::chrono::time_point

    原 总结 STL 标准库 chrono time_point ratio  概览 类定义 总结 思考 拓展 system_clock steady_clock high_resolution_cloc ...

  3. [原]C++新标准之std::ratio

    原 总结 ratio  概览 类定义 预定义ratio 应用 示例代码 参考资料 概览 std::ratio定义在<ratio>文件中,提供了编译期的比例计算功能.为std::chrono ...

  4. mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)

    我正在安装 mingw-w64 on Windows,有两个选项: win32线程和posix线程. 我知道win32线程和pthreads之间的区别,但是我不明白这两个选项之间的区别. 我怀疑如果我 ...

  5. C++ std::thread概念介绍

    C++ 11新标准中,正式的为该语言引入了多线程概念.新标准提供了一个线程库thread,通过创建一个thread对象来管理C++程序中的多线程. 本文简单聊一下C++多线程相关的一些概念及threa ...

  6. 第25课 std::thread对象的析构

    一. 线程的等待与分离 (一)join和detach函数 1. 线程等待:join() (1)等待子线程结束,调用线程处于阻塞模式. (2)join()执行完成之后,底层线程id被设置为0,即join ...

  7. C++11 并发指南------std::thread 详解

    参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...

  8. std::thread使用

    本文将从以下三个部分介绍C++11标准中的thread类,本文主要内容为: 启动新线程 等待线程与分离线程 线程唯一标识符 1.启动线程 线程再std::threada对象创建时启动.最简单的情况下, ...

  9. C++11并发——多线程std::thread (一)

    https://www.cnblogs.com/haippy/p/3284540.html 与 C++11 多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是< ...

随机推荐

  1. java课程之团队开发第一阶段评论

    1.没有UI设计,整体的样式感觉不堪入目 2.功能方面实现的并不是很多,还需要继续努力 3.还需要添加一些常用的课表功能,比如说导入课表等

  2. java: 集合collection

    collection是集合层次结构中的根接口,一些集合允许重复元素,而其他集合不允许. 有些collection是有序的,而另一些是无序的. JDK不提供此接口的任何直接实现:它提供了更具体的子接口的 ...

  3. python 进程和线程(2)

    这篇博客是按照博客<进程和线程(1)>中内容用futures改写  with futures.ProcessPoolExecutor() as executor:可以两篇博客对照看. 2改 ...

  4. sendmail 的安装、配置与发送邮件的具体实现

    Ubuntu 中sendmail 的安装.配置与发送邮件的具体实现 centos安装sendmail与使用详解 CentOS下搭建Sendmail邮件服务器 使用外部SMTP发送邮件  使用mailx ...

  5. python 设置系统/用户环境变量

    系统环境变量 winreg.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' 用户环境变 ...

  6. 哈希表hashTable的Java设计

    1:哈希表的概念 2:设计原理 3:哈希表的Java设计

  7. Microsoft SQL server Management Studio工具报错“应用程序的组件中发生了无法处理的异常”

    解决办法 打开目录: C:\Documents and Settings\Administrator\Application Data\Microsoft\Microsoft SQL Server\1 ...

  8. opencv摄像头捕获视频

    1.ord()函数:它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 ...

  9. 2020/1/29 PHP代码审计之进一步学习XSS【持续更新】

    0x00 上午学习了XSS漏洞,中午吃饭想了想,还是思考的太浅层了,这种老生常谈的东西对于现在的我意义不大.现在我需要的是思考.于是就有了这个随笔.在本文中,我会持续更新一些XSS的深入思考,payl ...

  10. 2019.11.18CTFD搭建记录

    ### 0x01 实验室纳新,准备在自己服务器搭建个ctfd给新生们玩玩,忙活了一天orz[大一刚开学就搭建过没这么费力啊..] 现在大二了没想到能折腾一天... 直接说下我踩的坑吧,给后来的人们说说 ...