首页 > 其他分享 >转移线程所有权

转移线程所有权

时间:2024-03-24 21:45:41浏览次数:20  
标签:std thread move t2 t1 线程 所有权 转移

假设要写一个在后台启动线程的函数, 想通过新线程返回的所有权去调用这个函数, 而不是等待线程结束再去调用; 或完全与之相反的想法: 创建一个线程, 并在函数中转移所有权,都必须要等待线程结束。 总之, 新线程的所有权都需要转移。这就是移动引入 std::thread 的原因。

C++标准库中有很多资源占有(resource-owning)类型,比如 std::ifstream , std::unique_ptr 还有 std::thread 都是可移动(movable), 但不可拷贝(not cpoyable)。 这就说明执行线程的所有权可以在 std::thread 实例中移动, 下面将展示一个例子。

void some_function();
void some_other_function();
std::thread t1(some_function); // 1
std::thread t2=std::move(t1); // 2
t1=std::thread(some_other_function); // 3
std::thread t3; // 4
t3=std::move(t2); // 5
t1=std::move(t3); // 6 赋值操作将使程序崩溃
  • 当显式使用 std::move() 创建t2后②, t1的所有权就转移给了t2。 之后, t1和执行线程已经没有关联了; 执行some_function的函数现在与t2关联。 
  • 然后, 与一个临时 std::thread 对象相关的线程启动了③为什么不显式调用 std::move() 转移所有权呢? 因为, 所有者是一个临时对象——移动操作将会隐式的调用。 
  •  t3使用默认构造方式创建④, 与任何执行线程都没有关联。 调用 std::move() 将与t2关联线程的所有权转移到t3中⑤。 因为t2是一个命名对象, 需要显式的调用 std::move()。
  • 最后一个移动操作, 将some_function线程的所有权转移⑥给t1。 不过, t1已经有了一个关联的线程(执行some_other_function的线程), 所以这里系统直接调用 std::terminate() 终止程序继续运行。 终止操作将调用 std::thread 的析构函数, 销毁所有对象。

std::thread 对象的容器, 如果这个容器是移动敏感的(比如, 标准中的 std::vector<> ), 那么移动操作同样适用于这些容器。

void do_work(unsigned id);
void f()
{
    std::vector<std::thread> threads;
    for(unsigned i=0; i < 20; ++i)
    {
        threads.push_back(std::thread(do_work,i)); // 产生线程
    }
    std::for_each(threads.begin(),threads.end(),
                     std::mem_fn(&std::thread::join)); // 对每个线程调用join()
}

 

标签:std,thread,move,t2,t1,线程,所有权,转移
From: https://www.cnblogs.com/love-9/p/18093133

相关文章

  • 向线程函数传递参数
    向std::thread构造函数中的可调用对象,或函数传递一个参数很简单。需要注意的是,默认参数要拷贝到线程独立内存中,即使参数是引用的形式,也可以在新线程中进行访问 。voidf(inti,std::stringconst&s);std::threadt(f,3,"hello");代码创建了一个调用f(3,"hello")的......
  • 等待线程完成
     如果不等待线程,就必须保证线程结束之前,可访问的数据得有效性。 这种情况很可能发生在线程还没结束,函数已经退出的时候,这时线程函数还持有函数局部变量的指针或引用。 structfunc{int&i;func(int&i_):i(i_){}voidoperator()(){fo......
  • 线程启动
     线程在std::thread对象创建(为线程指定任务)时启动。最简单的情况下,任务也会很简单,通常是无参数无返回(void-returning)的函数 。 使用C++线程库启动线程,可以归结为构造std::thread对象: voiddo_some_work();std::threadmy_thread(do_some_work);为了让编译器识......
  • 简易的取款多线程
    首先建立一个classAccount类,设置全局变量money,这个变量会被所有的线程使用。设置条件。classAccount{publicstaticintmoney=3000;//建立全局变量publicsynchronizedvoidtaking(intm){if(m>money){System.out.println("余额不足");}else{System.out.pr......
  • JAVAEE——多线程的设计模式,生产消费模型,阻塞队列
    文章目录多线程设计模式什么是设计模式单例模式饿汉模式懒汉模式线程安全问题懒汉模式就一定安全吗?锁引发的效率问题jvm的优化引起的安全问题阻塞队列阻塞队列是什么?生产消费者模型阻塞队列实现消费生产者模型可能遇到的异常多线程设计模式什么是设计模式首先我......
  • 【C++】Linux多线程开发
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录3.1线程概述3.2创建线程3.3、线程终止3.4连接已经终止线程3.5线程的分离3.6线程取消3.7线程属性3.8线程同步3.9互斥锁3.10死锁3.11读写锁3.12生产者和消费者模型3.13条件......
  • 分类预测 | Matlab实现MTF-CNN-Mutilhead-Attention马尔可夫转移场卷积网络多头注意力
    分类预测|Matlab实现MTF-CNN-Mutilhead-Attention马尔可夫转移场卷积网络多头注意力机制多特征分类预测/故障识别目录分类预测|Matlab实现MTF-CNN-Mutilhead-Attention马尔可夫转移场卷积网络多头注意力机制多特征分类预测/故障识别分类效果基本介绍模型描述程序设......
  • Java面试题:用Java并发工具类,实现一个线程安全的单例模式;使用Java并发工具包和并发框架
    面试题一:设计一个Java并发工具类,实现一个线程安全的单例模式,并说明其工作原理。题目描述:请设计一个Java并发工具类,实现一个线程安全的单例模式。要求使用Java内存模型、原子操作、以及Java并发工具包中的相关工具。考察重点:对Java内存模型的理解。对Java并发工具包的了......
  • Linux线程互斥
    文章目录Linux线程互斥mutex接口初始化互斥量销毁互斥量加锁和解锁加锁解锁的原理使用示例Linux线程互斥进程线程间的互斥相关背景概念临界资源:多线程执行流共享的资源就叫做临界资源临界区:每个线程内部,访问临界资源的代码,就叫做临界区互斥:任何时刻,互斥保证有......
  • ftp多线程下载工具
    //代码类似https多线程下载,整体实现逻辑类似,区别比较大的是curl_opt的相关参数设置不一样#include<iostream>#include<fstream>#include<curl/curl.h>#include<pthread.h>#include<sys/mman.h>#include<sys/stat.h>#include<fcntl.h>#include<sys......