zoukankan      html  css  js  c++  java
  • 【C++高级编程 | 23】future、packaged_task等使用机制

    call_onced

    简介 - 原文链接:https://blog.csdn.net/xijiacun/article/details/71023777

    #include <mutex>
    template <class Fn, class... Args>
    void call_once(once_flag &flag, Fn &&fn, Args &&... args);

    第一个参数是std::once_flag的对象(once_flag是不允许修改的,其拷贝构造函数和operator=函数都声明为delete),第二个参数可调用实体,即要求只执行一次的代码,后面可变参数是其参数列表。

            call_once保证函数fn只被执行一次,如果有多个线程同时执行函数fn调用,则只有一个活动线程(active call)会执行函数,其他的线程在这个线程执行返回之前会处于”passive execution”(被动执行状态)——不会直接返回,直到活动线程对fn调用结束才返回。对于所有调用函数fn的并发线程,数据可见性都是同步的(一致的)。 

        如果活动线程在执行fn时抛出异常,则会从处于”passive execution”状态的线程中挑一个线程成为活动线程继续执行fn,依此类推。一旦活动线程返回,所有”passive execution”状态的线程也返回,不会成为活动线程。(实际上once_flag相当于一个锁,使用它的线程都会在上面等待,只有一个线程允许执行。如果该线程抛出异常,那么从等待中的线程中选择一个,重复上面的流程)

    注意: once_flag的生命周期,它必须要比使用它的线程的生命周期要长。所以通常定义为全局变量。

    1. 示例

     1 #include <thread>
     2 #include <iostream>
     3 #include <mutex>
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 once_flag gOnceFlag;
     9 
    10 void initializeSharedResources() {
    11     cout << "Shared resources initialized." << endl;
    12 }
    13 
    14 void processingFunction() {
    15     call_once(gOnceFlag, initializeSharedResources);
    16     cout << "Processing" << endl;
    17 }
    18 
    19 int main() {
    20     vector<thread> threads(3);
    21     for (auto &t : threads) {
    22         t = thread{processingFunction};
    23     }
    24 
    25     for (auto &t : threads) {
    26         t.join();
    27     }
    28 
    29     return 0;
    30 }

    std::future 介绍

    1. future图解

     

     1 #include <iostream>
     2 #include <thread>
     3 #include <future>
     4 
     5 using namespace std;
     6 
     7 void DoWork(promise<int> thePromise)
     8 {
     9     thePromise.set_value(42);
    10 }
    11 
    12 int main()
    13 {
    14     promise<int> myPromise;
    15     std::future<int> theFuture = myPromise.get_future();
    16     thread theThread{DoWork, std::move(myPromise)};
    17     int result = theFuture.get();
    18 
    19     cout << "Result: " << result << endl;
    20     theThread.join();
    21 
    22     return 0;
    23 }

    std::packaged_task

     1 #include <iostream>
     2 #include <thread>
     3 #include <future>
     4 using namespace std;
     5 
     6 int CalculateSum(int a, int b)
     7 {
     8     return a + b;
     9 }
    10 
    11 int main()
    12 {
    13     packaged_task<int(int, int)> task(CalculateSum);
    14     std::future<int> theFuture = task.get_future();
    15     thread theThread{ std::move(task), 39, 3 };
    16     int result = theFuture.get();
    17     cout << result << endl;
    18     theThread.join();
    19     return 0;
    20 }
     1 #include <iostream>
     2 #include <thread>
     3 #include <future>
     4 
     5 using namespace std;
     6 
     7 void DoWork(promise<int> thePromise)
     8 {
     9     thePromise.set_value(42);
    10 }
    11 
    12 int main()
    13 {
    14     promise<int> myPromise;
    15     std::future<int> theFuture = myPromise.get_future();
    16     thread theThread{DoWork, std::move(myPromise)};
    17     int result = theFuture.get();
    18 
    19     cout << "Result: " << result << endl;
    20     theThread.join();
    21 
    22     return 0;
    23 }

     

    参考资料

    1. C++11之std::future对象使用说明

    2. C++11多线程编程 第八章: 使用 std::future std::promise 更优雅的获取线程返回值

  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/sunbines/p/14587435.html
Copyright © 2011-2022 走看看