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++ 11 多线程支持 (std::packaged_task) -> 正文阅读

[C++知识库]c++ 11 多线程支持 (std::packaged_task)

定义于头文件 <future>
template< class > class packaged_task; // 不定义  (1) (C++11 起) 

template< class R, class ...Args >
class packaged_task<R(Args...)>;                  (2) (C++11 起) 

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

正如 std::function , std::packaged_task 是多态、具分配器的容器:可在堆上或以提供的分配器分配存储的可调用对象。

构造函数

std::packaged_task<R(Args...)>::packaged_task
packaged_task() noexcept;   (1) (C++11 起) 

template <class F>
explicit packaged_task( F&& f ); (2) (C++11 起) 

template <class F, class Allocator>
explicit packaged_task( std::allocator_arg_t, const Allocator& a, F&& f );
(3) (C++11 起)  (C++17 前) 

packaged_task( const packaged_task& ) = delete; (4) (C++11 起) 

packaged_task( packaged_task&& rhs ) noexcept;  (5) (C++11 起) 

构造新的 std::packaged_task 对象。

1) 构造无任务且无共享状态的 std::packaged_task 对象。

2) 构造拥有共享状态和任务副本的 std::packaged_task 对象,以 std::forward<F>(f) 初始化副本。若 std::decay<F>::type 与 std::packaged_task<R(ArgTypes...)> 是同一类型,则此构造函数不参与重载决议。

3) 构造拥有共享状态和任务副本的 std::packaged_task 对象,以 std::forward<F>(f) 初始化副本。用提供的分配器分配存储任务所需的内存。 若 std::decay<F>::type 与 std::packaged_task<R(ArgTypes...)> 是同一类型,则此构造函数不参与重载决议。

4) 复制构造函数被删除, std::packaged_task 仅可移动。

5) 以 rhs 之前所占有的共享状态和任务构造 std::packaged_task ,令 rhs 留在无共享状态且拥有被移动后的任务的状态。

参数

f-要执行的可调用目标(函数、成员函数、 lambda 表达式、函数对象)
a-存储任务时所用的分配器
rhs-要移动的 std::packaged_task

异常

2) f 的复制/移动构造函数所抛的任何异常,而若内存分配失败则可能为 std::bad_alloc 。

3) f 的复制/移动构造函数,而若内存分配失败则有分配器的 allocate 函数所抛的任何异常。

4) (无)

析构函数

std::packaged_task<R(Args...)>::~packaged_task
~packaged_task();

抛弃共享状态并销毁存储的任务对象。

同 std::promise::~promise ,若在令共享状态就绪前抛弃它,则存储以 std::future_errc::broken_promise 为 error_code 的 std::future_error 异常。

参数

(无)

移动任务对象

std::packaged_task<R(Args...)>::operator=
packaged_task& operator=( const packaged_task& ) = delete; (1) (C++11 起) 

packaged_task& operator=( packaged_task&& rhs ) noexcept;  (2) (C++11 起) 

1) 复制赋值运算符被删除, std::packaged_task 仅可移动。

2) 若存在则释放共享状态,销毁先前保有的任务,并将 rhs 所占有的共享状态和任务移动到 *this 。令 rhs 无共享状态,并拥有被移动后的任务。

参数

rhs-移动来源的 std::packaged_task

检查任务对象是否拥有合法函数

std::packaged_task<R(Args...)>::valid
bool valid() const noexcept;  (C++11 起) 

检查 *this 是否拥有共享状态。

参数

(无)

返回值

若 *this 拥有共享状态则为 true ,否则为 false 。

交换二个任务对象

std::packaged_task<R(Args...)>::swap
void swap( packaged_task& other ) noexcept;   (C++11 起) 

交换 *this 与 other 的共享状态和存储的任务。

参数

other-要交换状态的 packaged_task

返回值

(无)

返回与承诺的结果关联的 std::future

std::packaged_task<R(Args...)>::get_future
std::future<R> get_future();    (C++11 起) 

返回与 *this 共享同一共享状态的 future

get_future 只能对每个 packaged_task 调用一次。

参数

(无)

返回值

与 *this 共享同一共享状态的 future

异常

遇到下列条件时为 std::future_error 。

  • 已通过调用 get_future 取得共享状态。设置 error_category 为 future_already_retrieved 。
  • *this 无共享状态。设置 error_category 为 no_state 。


执行函数

std::packaged_task<R(Args...)>::operator()
void operator()( ArgTypes... args );   (C++11 起) 

args 为参数调用存储的任务。任务返回值或任何抛出的异常被存储于共享状态。令共享状态就绪,并解除阻塞任何等待此操作的线程。

参数

args-调用时传递给存储任务的参数

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • 已调用存储的任务。设置 error_category 为 promise_already_satisfied 。
  • *this 无共享状态。设置 error_category 为 no_state 。

注意

operator() 的成功调用同步于对任何与 *this 共享其共享状态的 std::future 或 std::shared_future 的任何成员函数调用。

(C++14 前)

在共享状态已提供的同步保证外,无另外的同步保证。

(C++14 起)

?

重置状态,抛弃任何先前执行的存储结果

?std::packaged_task<R(Args...)>::reset
void reset();              (C++11 起) 

重置状态,抛弃先前执行的结果。构造共享状态。

等价于 *this = packaged_task(std::move(f)) ,其中 f 是存储的任务。

参数

(无)

返回值

(无)

异常

  • 若 *this 无共享状态则为 std::future_error 。设置 error_condition 为 no_state 。
  • 若无足够内存以分配新的共享状态则为 std::bad_alloc 。
  • packaged_task 的移动构造函数所抛的任何异常

执行函数,并确保结果仅在一旦当前线程退出时就绪

std::packaged_task<R(Args...)>::make_ready_at_thread_exit
void make_ready_at_thread_exit( ArgTypes... args );   (C++11 起) 

void make_ready_at_thread_exit( ArgTypes... args );

(C++11 起)

以转发的 args 为参数调用存储的任务。任务返回值或任何抛出的异常被存储于 *this 的共享状态。

仅在当前线程退出,并销毁所有线程局域存储期对象后,才令共享状态就绪。

参数

args-调用时传递给存储任务的参数

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • 已调用存储的任务。设置 error_category 为 promise_already_satisfied 。
  • *this 无共享状态。设置 error_category 为 no_state 。

调用示例

#include <future>
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <utility>

void worker(std::future<void>& output)
{
    std::packaged_task<void(bool&)> my_task{ [](bool & done)
    {
        done = true;
    } };

    auto result = my_task.get_future();

    bool done = false;

    my_task.make_ready_at_thread_exit(done); // 立即执行任务

    std::cout << "worker: done = " << std::boolalpha << done << std::endl;

    auto status = result.wait_for(std::chrono::seconds(0));
    if (status == std::future_status::timeout)
    {
        std::cout << "worker: result is not ready yet" << std::endl;
    }

    output = std::move(result);
}


int main()
{
    std::future<void> result;

    std::thread{worker, std::ref(result)}.join();

    auto status = result.wait_for(std::chrono::seconds(0));
    if (status == std::future_status::ready)
    {
        std::cout << "main: result is ready" << std::endl;
    }
}

输出

特化 std::swap 算法

std::swap(std::packaged_task)
template< class Function, class... Args >
void swap( packaged_task<Function(Args...)> &lhs,
           packaged_task<Function(Args...)> &rhs ) noexcept;  (C++11 起) 

? ? ? ? ? ?packaged_task<Function(Args...)> &rhs ) noexcept;

(C++11 起)

为 std::packaged_task 特化 std::swap 算法。交换 lhsrhs 的状态。等效地调用 lhs.swap(rhs) 。

参数

lhs, rhs-要交换状态的 packaged_task

返回值

(无)

调用示例

#include <iostream>
#include <cmath>
#include <thread>
#include <future>
#include <functional>

// 避免对 std::pow 重载集消歧义的独有函数
int f(int x, int y)
{
    return std::pow(x, y);
}

void task_lambda()
{
    std::packaged_task<int(int, int)> task([](int a, int b)
    {
        return std::pow(a, b);
    });
    std::future<int> result = task.get_future();

    task(2, 9);

    std::cout << "task_lambda:\t" << result.get() << '\n';
}

void task_bind()
{
    std::packaged_task<int()> task(std::bind(f, 2, 11));
    std::future<int> result = task.get_future();

    task();

    std::cout << "task_bind:\t" << result.get() << '\n';
}

void task_thread()
{
    std::packaged_task<int(int, int)> task(f);
    std::future<int> result = task.get_future();

    std::thread task_td(std::move(task), 2, 10);
    task_td.join();

    std::cout << "task_thread:\t" << result.get() << '\n';
}

int main()
{
    task_lambda();
    task_bind();
    task_thread();
}

输出

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 00:51:43  更:2022-09-04 00:54:06 
 
开发: 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 10:55:50-

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