上一篇博客《C++11 并发指南一(C++11 多线程初探)》中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用法。
std::thread 在 <thread> 头文件中声明,因此使用 std::thread 时需要包含 <thread> 头文件。
std::thread 构造
default (1) | thread() noexcept; |
---|---|
initialization (2) | template <class Fn, class... Args> explicit thread (Fn&& fn, Args&&... args); |
copy [deleted] (3) | thread (const thread&) = delete; |
move (4) | thread (thread&& x) noexcept; |
(1). 默认构造函数,创建一个空的 thread 执行对象。
(2). 初始化构造函数,创建一个 thread对象,该 thread对象可被 joinable,新产生的线程会调用 fn 函数,该函数的参数由 args 给出。
(3). 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
(4). move 构造函数,move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached.
std::thread 各种构造函数例子如下(参考):
#include <iostream> #include <utility> #include <thread> #include <chrono> #include <functional> #include <atomic> void f1(int n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread " << n << " executing\n"; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void f2(int& n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread 2 executing\n"; ++n; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } int main() { int n = 0; std::thread t1; // t1 is not a thread std::thread t2(f1, n + 1); // pass by value std::thread t3(f2, std::ref(n)); // pass by reference std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread t2.join(); t4.join(); std::cout << "Final value of n is " << n << '\n'; }
move 赋值操作
move (1) | thread& operator= (thread&& rhs) noexcept; |
---|---|
copy [deleted] (2) | thread& operator= (const thread&) = delete; |
(1). move 赋值操作,如果当前对象不可 joinable,需要传递一个右值引用(rhs)给 move 赋值操作;如果当前对象可被 joinable,则 terminate() 报错。
(2). 拷贝赋值操作被禁用,thread 对象不可被拷贝。
请看下面的例子:
#include <stdio.h> #include <stdlib.h> #include <chrono> // std::chrono::seconds #include <iostream> // std::cout #include <thread> // std::thread, std::this_thread::sleep_for void thread_task(int n) { std::this_thread::sleep_for(std::chrono::seconds(n)); std::cout << "hello thread " << std::this_thread::get_id() << " paused " << n << " seconds" << std::endl; } /* * === FUNCTION ========================================================= * Name: main * Description: program entry routine. * ======================================================================== */ int main(int argc, const char *argv[]) { std::thread threads[5]; std::cout << "Spawning 5 threads...\n"; for (int i = 0; i < 5; i++) { threads[i] = std::thread(thread_task, i + 1); } std::cout << "Done spawning threads! Now wait for them to join\n"; for (auto& t: threads) { t.join(); } std::cout << "All threads joined.\n"; return EXIT_SUCCESS; } /* ---------- end of function main ---------- */
其他成员函数
get_id
获取线程 ID。
joinable
检查线程是否可被 join。
join
Join 线程。
detach
Detach 线程
swap
Swap 线程 。
native_handle
返回 native handle。
hardware_concurrency [static]
检测硬件并发特性。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍C++11 并发指南之std::mutex详解,包括了C++11 并发指南之std::mutex详解的使用技巧和注意事项,需要的朋友参考一下 上一篇《C++11 并发指南二(std::thread 详解) 》中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法。 Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(
本文向大家介绍C++11 并发指南之Lock 详解,包括了C++11 并发指南之Lock 详解的使用技巧和注意事项,需要的朋友参考一下 在 《 C++11 并发指南三(std::mutex 详解) 》一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型。本节将详细介绍一下 C++11 标准的锁类型。 C++11 标准为我们提供了两种基本的锁类型,分别如下: s
本文向大家介绍C++11 并发指南之多线程初探,包括了C++11 并发指南之多线程初探的使用技巧和注意事项,需要的朋友参考一下 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧,和大家共勉。 相信 Linux 程序员都用过 Pthread, 但有了 C++
本书《C++ 并发编程指南》是个人在空余时间写的,由于时间仓促,加上自身水平有限,不可能写的很完善,也难免出现错误,如果你发现本书中的错误,或者有更好的想法, 欢迎给我反馈,我会第一时间给予答复。后续我会坚持完善这一系列的文章。也希望感兴趣的同学和我一起完成。 本书的创作出于以下两个目的: 传播知识,介绍 C++ 并发编程。目前国内还没有一本完整介绍 C++11 并发编程的中文书籍,希望本书可以帮
在设计回调函数的时候,无可避免地会接触到可回调对象。在C++11中,提供了std::function和std::bind两个方法来对可回调对象进行统一和封装。 可调用对象 C++中有如下几种可调用对象:函数、函数指针、lambda表达式、bind对象、函数对象。其中,lambda表达式和bind对象是C++11标准中提出的(bind机制并不是新标准中首次提出,而是对旧版本中bind1st和bind
当学习C++的时候,数组是最基本的结构之一,通常通过以下的方式来定义: int a[5]; int *b = new int[5]; 上面一句是在栈上定义了一个长度为5的数组,下面一句是在堆上定义了一个长度为5的数组,并用一个指针指向它。 在C++11中,引入了一种新的数组定义方式std::array。 std::array的特性 std::array是具有固定大小的数组。因此,它并不支持添加或