【C++标准库】并发

2021-07-20 06:07

阅读:367

标签:auto   tutorial   seconds   多个   enc   done   iso   appears   cin   

高级接口async()和future

/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
* by Nicolai M. Josuttis, Addison-Wesley, 2012
*
* (C) Copyright Nicolai M. Josuttis 2012.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include 
#include 
#include 
#include 
#include 
#include using namespace std;

int doSomething(char c)
{
    // random-number generator (use c as seed to get different sequences)
    std::default_random_engine dre(c);
    std::uniform_int_distributionint> id(10, 1000);

    // loop to print character after a random period of time
    for (int i = 0; i10; ++i) 
    {
        this_thread::sleep_for(chrono::milliseconds(id(dre)));
        cout.put(c).flush();
    }

    return c;
}

int func1()
{
    return doSomething(.);
}

int func2()
{
    return doSomething(+);
}

int main()
{
    std::cout "starting func1() in background"
        " and func2() in foreground:"  std::endl;

    // start func1() asynchronously (now or later or never):
    std::futureint> result1(std::async(func1));

    int result2 = func2();    // call func2() synchronously (here and now)

    // print result (wait for func1() to finish and add its result to result2
    int result = result1.get() + result2;

    std::cout "\nresult of func1()+func2(): "  result
         std::endl;
}

技术分享图片

class std::future提供了“处理并发运算之未来结果”的能力,但是get()只能调用一次,第二次调用get()会导致不可预期的行为。然而有时候,多次处理并发结果是合理的,特别是当多个线程都想处理这个结果时。基于这个目的,C++标准库提供了class std::shared_future,可以多次调用get(),得到相同的结果,或导致抛出一个异常。

技术分享图片技术分享图片
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
* by Nicolai M. Josuttis, Addison-Wesley, 2012
*
* (C) Copyright Nicolai M. Josuttis 2012.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include 
#include 
#include 
#include 
#include using namespace std;

int queryNumber()
{
    // read number
    cout "read number: ";
    int num;
    cin >> num;

    // throw exception if none
    if (!cin) {
        throw runtime_error("no number read");
    }

    return num;
}

void doSomething(char c, shared_futureint> f)
{
    try 
    {
        // wait for number of characters to print
        int num = f.get();  // get result of queryNumber()

        for (int i = 0; ii) 
        {
            this_thread::sleep_for(chrono::milliseconds(100));
            cout.put(c).flush();
        }
    }
    catch (const exception& e)
    {
        cerr "EXCEPTION in thread "  this_thread::get_id()
            ": "  endl;
    }
}

int main()
{
    try 
    {
        // start one thread to query a number
        shared_futureint> f = async(queryNumber);

        // start three threads each processing this number in a loop
        auto f1 = async(launch::async, doSomething, ., f);
        auto f2 = async(launch::async, doSomething, +, f);
        auto f3 = async(launch::async, doSomething, *, f);

        // wait for all loops to be finished
        f1.get();
        f2.get();
        f3.get();
    }
    catch (const exception& e) 
    {
        cout "\nEXCEPTION: "  endl;
    }
    cout "\ndone"  endl;
}
View Code

低层接口:Thread和Promise

/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
* by Nicolai M. Josuttis, Addison-Wesley, 2012
*
* (C) Copyright Nicolai M. Josuttis 2012.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include 
#include 
#include 
#include 
#include using namespace std;

void doSomething(int num, char c)
{
    try 
    {
        // random-number generator (use c as seed to get different sequences)
        default_random_engine dre(42 * c);
        uniform_int_distributionint> id(10, 1000);
        for (int i = 0; ii) 
        {
            this_thread::sleep_for(chrono::milliseconds(id(dre)));
            cout.put(c).flush();
            //...
        }
    }
    // make sure no exception leaves the thread and terminates the program
    catch (const exception& e) {
        cerr "THREAD-EXCEPTION (thread "
            "): "  endl;
    }
    catch (...) {
        cerr "THREAD-EXCEPTION (thread "
            ")"  endl;
    }
}

int main()
{
    try 
    {
        thread t1(doSomething, 5, .);  // print five dots in separate thread
        cout "- started fg thread "  endl;

        // print other characters in other background threads
        for (int i = 0; i5; ++i) {
            thread t(doSomething, 10, a + i); // print 10 chars in separate thread
            cout "- detach started bg thread "  endl;
            t.detach();  // detach thread into the background
        }

        cin.get();  // wait for any input (return)

        cout "- join fg thread "  endl;
        t1.join();  // wait for t1 to finish
    }
    catch (const exception& e) {
        cerr "EXCEPTION: "  endl;
    }
}

技术分享图片

/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
* by Nicolai M. Josuttis, Addison-Wesley, 2012
*
* (C) Copyright Nicolai M. Josuttis 2012.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include 
#include 
#include 
#include string>
#include 
#include 
#include 
#include void doSomething(std::promise<:>string>& p)
{
    try {
        // read character and throw exception if ‘x‘
        std::cout "read char (‘x‘ for exception): ";
        char c = std::cin.get();
        if (c == x) {
            throw std::runtime_error(std::string("char ") + c + " read");
        }
        //...
        std::string s = std::string("char ") + c + " processed";
        p.set_value_at_thread_exit(std::move(s));    // store result
    }
    catch (...) {
        p.set_exception_at_thread_exit(std::current_exception());  // store exception
    }
}

int main()
{
    try 
    {
        // create a promise to store the outcome
        std::promise<:>string> p;
        // create a future to process the outcome
        std::future<:>string> f(p.get_future());
        // start a thread using the promise to store the outcome
        std::thread t(doSomething, std::ref(p));
        t.detach();
        //...

        // process the outcome
        std::cout "result: " get()  std::endl;
    }
    catch (const std::exception& e) 
    {
        std::cerr "EXCEPTION: "  std::endl;
    }
    catch (...) 
    {
        std::cerr "EXCEPTION "  std::endl;
    }
}

 

【C++标准库】并发

标签:auto   tutorial   seconds   多个   enc   done   iso   appears   cin   

原文地址:https://www.cnblogs.com/larry-xia/p/9519949.html


评论


亲,登录后才可以留言!