IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++并发编程之线程异步std::packaged_task知识点总结 -> 正文阅读

[C++知识库]C++并发编程之线程异步std::packaged_task知识点总结

1、std::packaged_task介绍

类模板 std::packaged_task 包装任何可调用 (Callable) 目标(函数、 lambda 表达式、 bind 表达式或其他函数对象),使得能异步调用它。其返回值或所抛异常被存储于能通过 std::future 对象访问的共享状态中。—摘抄自https://www.apiref.com/cpp-zh/cpp/thread/packaged_task.html

接下来看下std::packaged_task的定义:

  /// packaged_task
  template<typename _Res, typename... _ArgTypes>
    class packaged_task<_Res(_ArgTypes...)>
    {
      typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type;
      shared_ptr<_State_type>                   _M_state;

    public:
      // Construction and destruction
      packaged_task() noexcept { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2095.  missing constructors needed for uses-allocator construction
      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
	{ }

      template<typename _Fn, typename = typename
	       __constrain_pkgdtask<packaged_task, _Fn>::__type>
	explicit
	packaged_task(_Fn&& __fn)
	: packaged_task(allocator_arg, std::allocator<int>(),
			std::forward<_Fn>(__fn))
	{ }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2097.  packaged_task constructors should be constrained
      template<typename _Fn, typename _Alloc, typename = typename
	       __constrain_pkgdtask<packaged_task, _Fn>::__type>
	explicit
	packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn)
	: _M_state(__create_task_state<_Res(_ArgTypes...)>(
		    std::forward<_Fn>(__fn), __a))
	{ }

      ~packaged_task()
      {
        if (static_cast<bool>(_M_state) && !_M_state.unique())
	  _M_state->_M_break_promise(std::move(_M_state->_M_result));
      }

      // No copy
      packaged_task(const packaged_task&) = delete;
      packaged_task& operator=(const packaged_task&) = delete;

      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator&,
		      const packaged_task&) = delete;

      // Move support
      packaged_task(packaged_task&& __other) noexcept
      { this->swap(__other); }

      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator&,
		      packaged_task&& __other) noexcept
	{ this->swap(__other); }

      packaged_task& operator=(packaged_task&& __other) noexcept
      {
	packaged_task(std::move(__other)).swap(*this);
	return *this;
      }

      void
      swap(packaged_task& __other) noexcept
      { _M_state.swap(__other._M_state); }

      bool
      valid() const noexcept
      { return static_cast<bool>(_M_state); }

      // Result retrieval
      future<_Res>
      get_future()
      { return future<_Res>(_M_state); }

      // Execution
      void
      operator()(_ArgTypes... __args)
      {
	__future_base::_State_base::_S_check(_M_state);
	_M_state->_M_run(std::forward<_ArgTypes>(__args)...);
      }

      void
      make_ready_at_thread_exit(_ArgTypes... __args)
      {
	__future_base::_State_base::_S_check(_M_state);
	_M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state);
      }

      void
      reset()
      {
	__future_base::_State_base::_S_check(_M_state);
	packaged_task __tmp;
	__tmp._M_state = _M_state;
	_M_state = _M_state->_M_reset();
      }
    };

2、std::packaged_task重要的函数介绍

void swap(packaged_task& __other);//两个packaged task互换
bool valid();//如果有一个新的shared state就产生true。
// Result retrieval
future<_Res> get_future();//获得一个future 对象,可以用来取的shared state
// Execution
void operator()(_ArgTypes... __args);
void make_ready_at_thread_exit(_ArgTypes... __args);
//调用task并且在线成退出时使shared state为ready
void reset(); //建立一个新的shared state,会使shared state为ready
/// swap
template<typename _Res, typename... _ArgTypes>
    swap(packaged_task<_Res(_ArgTypes...)>& __x, packaged_task<_Res(_ArgTypes...)>& __y);

3、std::packaged_task用法示例

具体示例代码如下:

/*************************************************************************
	> File Name: thread_packaged_task.cpp
	> Author: 小和尚敲木鱼
	> Mail:  
	> Created Time: Tue 21 Sep 2021 02:40:24 AM PDT
 ************************************************************************/

#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <list>
#include <mutex>
#include <future>
#include <chrono>

using namespace std;
/*****************************文件说明***********************************/
int function_1(int param)//线程
{
	int ret = 10;
	std::cout << __func__ << "param =" << param  << std::endl;
	std::cout << "handle thread id ="<< std::this_thread::get_id() << std::endl;
	std::chrono::milliseconds sleep_time(500);
	std::this_thread::sleep_for(sleep_time);
	std::cout << __func__ << " thread id ="<< std::this_thread::get_id() << std::endl;
	std::cout << __func__ << " return = "<< ret + param << std::endl;
	return (ret + param);
}

int main(int agc,char * agv[])
{
	int temp = 20;
	std::cout << "Main thread id =" << std::this_thread::get_id() << std::endl;
	std::packaged_task<int(int)> handle_task(function_1);//创建packaged_task
	std::thread thread_test(std::ref(handle_task),temp);


	std::future<int> result = handle_task.get_future();
	std::cout << "###################" << std::endl;
	std::cout << "result = " << result.get() << std::endl;
	
	if (thread_test.joinable())
		thread_test.join();

	return 0;
}
//OUT
//Main thread id =140609886185280
//###################
//function_1param =20
//handle thread id =140609868805888
//function_1 thread id =140609868805888
//function_1 return = 30
//result = 30
/**************************end of file**********************************/

4、总结

std::packaged_task简单来说就是,打包一个异步任务去完成,完成打包后就不用管了,到合适的地点去获取相应的执行结果就可以了。非常的银杏。
Todo:
后续补充其他细节。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:15:22  更:2021-10-12 23:15:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:40:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码