一、使用及接口
构造:std::thread、 thread th_(fn, args)
常用接口:joinable、detach 、join、get_id、swap、operator=(移动复制构造)
1、std::thread构造函数
1)默认构造: 创建一个空的std::thread执行对象
2)初始化构造: 创建一个std::thread对象,该 std::thread
对象可被 joinable
,新产生的线程会调用 fn
函数,该函数的参数由 args
给出。(此种方法,线程创建完成后,fn会立即执行。)
3)拷贝构造函数(被禁用),意味着 std::thread
对象不可拷贝构造。
4)Move 构造函数,move 构造函数(move 强制将一个左值转变为右值),调用成功之后 x
不代表任何 std::thread
执行对象。
#include <thread>
#include <chrono>
#include <iostream>
void f1(int n)
{
for (int i = 0; i < 5; ++i)
{
std::cout << "Thread " << n ;
std::this_thread::sleep_for(std::chrono::milliseconds(10)); //线程暂停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); // 值传递 产生一个新线程调用f1
std::thread t3(f2, std::ref(n)); // 引用传递 产生一个新线程调用f2
std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
//同步接口
t2.join(); //在此处暂停调用线程(main线程)后面的语句执行,直到t2、t4执行完毕。
t4.join();
std::cout << "Final value of n is " << n << '\n';
}
2、std::thread 赋值操作
1)Move 赋值操作(1),如果当前对象不可 joinable
,需要传递一个右值引用(rhs
)给 move
赋值操作;如果当前对象可被 joinable
,则会调用 terminate
() 报错。
2)拷贝赋值操作(2),被禁用,因此 std::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() << std::endl;
}
int main(int argc, const char *argv[])
{
std::thread threads[5];
for (int i = 0; i < 5; i++)
{
threads[i] = std::thread(thread_task, i + 1); //move赋值
}
for (auto& t: threads)
{
t.join();
}
std::cout << "All threads joined.\n";
return EXIT_SUCCESS;
}
3、joinable、join 、detach
1) joinable :检查线程是否可被 join。检查当前的线程对象是否表示了一个活动的执行线程。
由默认构造函数创建的线程是不能被 join 的。如果某个线程 已经执行完任务,但是没有被 join 的话,该线程依然会被认为是一个活动的执行线程,因此也是可以被 join 的。
2)join: 阻塞当前线程。
直到由 *this 所标示的线程执行完毕 join 才返回。
3)detach: 将当前线程对象所代表的执行实例与该线程对象分离。
使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。
调用 detach 函数之后:
*this
不再代表任何的线程执行实例。- joinable() == false
- get_id() == std::thread::id()4
4)swap: 交换两个线程底层句柄。
参考:
1、https://www.runoob.com/w3cnote/cpp-std-thread.html
2、http://www32.cplusplus.com/reference/thread/thread/detach/
转载请标明出处:https://blog.csdn.net/youtiao_hulatang/article/details/105221055