C++11中线程所有权转移分析

移动特性说明

C++标准库中有很多资源占有(resource-owning)类型,比如std::ifstream,std::unique_ptr还有std::thread都是可移动,但不可拷贝。

移动拷贝或者移动赋值都使得原有对象对所属资源的控制权发生转移,从对象A转移到对象B,对资源的控制只在对象B中保留。

以下是std::thread线程类的移动特性的声明,支持移动构造和移动对象,但不可拷贝。

//移动构造函数
thread( thread&& other ) noexcept;

//移动对象
thread& operator=( thread&& other ) noexcept;

//复制构造函数被删除
thread(const thread&) = delete;

以下两种情形都将发生线程类对象的移动操作,例如:

//返回thread参数
std::thread get_thread()
{
    //方式一:
    //return  std::thread (do_fun, 100);

    //方式二:
    std::thread td(do_fun, 100);
    return td;
}

//传递thread参数
void move_thread(std::thread td)
{
}

在C++ 11中标准库中,提供了std::move函数用于资源移动操作,这个一般应用于命名类对象std::thread td1,其函数声明如下:

template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept;

std::move 用于指示对象 t 可以“被移动”,即允许从 t 到另一对象的有效率的资源传递。

线程移动操作变化说明

当一个std::thread对象执行移动操作后,线程的所有权将发生转移,原有线程对象的相关标识被清空,失去线程的控制权。其原有线程类对象ID变为0,joinable变为为false。

代码说明如下:

void do_fun(int num)
{
    ++num;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int num = 10;
    //原有对象
    std::thread   task(do_fun, num);
    std::cout << "before call move task thread id is " << task.get_id() << std::endl;
    std::cout << "before call move task thread joinable status is " << task.joinable() << std::endl;
    
	//发生移动操作
    std::thread move_task = std::move(task);
  
    std::cout << "\nafter call move task thread id is " << task.get_id() << std::endl;
    std::cout << "after call move task thread  joinable status is " << task.joinable() << std::endl;

    std::cout << "\nmove_task  thread id is " << move_task.get_id() << std::endl;
    std::cout << "move_task thread joinable status is " << move_task.joinable() << std::endl;

    //如果joinable为false, 调用join 程序异常,
    //移动后task对象的joinable为false
    if (task.joinable())
    {
        task.join();
        std::cout << "call task  member function " << std::endl;
    }

    //如果joinable为false, 调用join 程序异常
    if (move_task.joinable())
    {
        move_task.join();
        std::cout << "call move_task  member function " << std::endl;
    }
}

 运行结果:

before call move task thread id is 17512
before call move task thread joinable status is 1

after call move task thread id is 0
after call move task thread  joinable status is 0

move_task  thread id is 17512
move_task thread joinable status is 1
call move_task  member function

下面就利用线程的移动特性,进行量产线程,并等待它们结束。

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()
}

本文转自:C++11中线程所有权转移分析_Keep Moving~-CSDN博客_c 线程转移

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值