C++11 std::thread的使用

一、使用及接口

构造: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

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大锅菜~

谢谢鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值