C++11 Creating an asynchronous program using Std::async

Source: Internet
Author: User

The addition of threads in C++11 allows us to create threads very conveniently, and its basic usage is this:

void f (1); t.join (); 

But the thread is a relatively low-level thing, sometimes use some inconvenience, such as I want to get the results of the thread function, I can not directly through the Thread.Join () to get results, then you have to define a variable, the thread function to assign a value to the variable, and then join, In the end, the process is more cumbersome. The C++11 also provides asynchronous interface Std::async, which makes it easy to get the execution results of a thread function through this asynchronous interface. Std::async automatically creates a thread to invoke the thread function, which returns a std::future that stores the results returned by the thread function, which is handy when we need the results of a thread function to be obtained directly from the future. But what I'm trying to say is that the convenience that Std::async gives us is not just this, it first decouples the creation and execution of threads, so that we can get the results of asynchronous operations when we need them, and secondly it provides thread creation strategies (such as the ability to create threads by delaying loading). Makes it possible to create threads in a variety of ways. Before describing the specific use of async and why you should use Std::async instead of creating threads, I would like to first say Std::future, std::p romise and std::p ackaged_task.

Std::future

Std::future is a very useful and interesting thing, simply said Std::future provides a mechanism to access the results of asynchronous operations. In the literal sense, it represents the future, I think the name is very appropriate, because an asynchronous operation we can not immediately get the results of the operation, can only be obtained at some point in the future, but we have a synchronous wait to obtain the results, you can query the status of the Futures (future_ Status) to get the result of an asynchronous operation. There are three states of Future_status:

    • Deferred: Asynchronous operation hasn't started yet
    • Ready: Asynchronous operation completed
    • Timeout: Asynchronous operation timed out
//Querying the status of the futureStd::future_status status;do {status = Future.wait_for (Std::chrono::seconds (1)); if (status = std::future_status::d eferred) {cout <<  "deferred\n";} else if (status = = std::future_status::timeout) {std::cout << timeout\n ";} else if (status = = std::future_status::ready) {std::cout << ready!\n";}} while (status! = std::future_status::ready);      

There are three ways to get a future result: get, wait, wait_for, where get waits for an asynchronous operation to end and returns a result, wait waits for the asynchronous operation to complete, no return value, and wait_for is timed out waiting for the result to return.

std::p romise

std::p romise is a convenient way to get a value from a thread function, and the promise assignment is given to the outside in the thread function, which can be obtained by promis after the execution of the threaded function is completed. It is important to note that the value is indirectly obtained through the future provided internally by the promise. Its basic usage:

std::p romise<int> PR;    std:: Thread T ([] (std::p romise<int>& p) {p.set_value_at_thread_exit (9);},std :std:: Future<int> f = pr.get_future (); auto R = F.get ();        
std::p ackaged_task

std::p Ackaged_task It wraps a callable target (such as function, lambda expression, bind expression, or another function object) so that it can be called asynchronously, It's kind of like promise to a certain extent, promise saves a shared state value, and Packaged_task saves a function. Its basic usage:

std:7;});    std:: Thread T1 (std::std:: Future<int> f1 = task.get_future (); auto R1 = F1.get (); 
                
std::p romise, std: Relationship between:p Ackaged_task and Std::future

So far, we have introduced several Std::async related objects std::future, std::p romise and std::p ackaged_task, where std::p romise and std::p ackaged_ The result of the task is eventually returned through its internal future, do not know whether the reader confused, why there are so many things out, what is the relationship between them? And listen to me slowly, Std::future provides a mechanism to access the results of an asynchronous operation, and the thread is a level of low-leveled object, above it is std::p ackaged_task and std::p romise, They have a future inside them. To access the results of asynchronous operations, std::p ackaged_task is wrapped in an asynchronous operation, and std::p romise is packaged as a value for asynchronous operation, because sometimes I need to get a value in the thread, then I use std: :p Romise, and sometimes I need to get a return value for an asynchronous operation, I use std::p ackaged_task. std::p romise and std: What's the relationship between:p Ackaged_task? It's up to you to say that they have nothing to do with it, and it all depends on you, because I can save the result of an asynchronous operation to std::p romise. If the reader is not clear about their relationship, I will explain it in more popular words. For example, when a young man gives a girl a true heart, he may say, "I promise to give you a good future" or "I will strive to make a good future for you". Girls tend to say, "I'm waiting." Now I'm going to translate these three sentences with c++11:

The lad said: I promise to give you a good future equals C++11 "std::p romise a std::future";
The lad said: I will strive for you to create a better future equals C++11 "std::p ackaged_task a Futures";
The girl said: I wait equals c++11 in "Future.get ()/wait ()";

The difference between the two words of the lad, himself pondering, this difference is also std::p romise and std::p ackaged_task difference. In reality, I do not rely on the commitment to live I do not know, but the promise of c++11 and the future is certain reliable, the initiation of the promise there must be a future. Think of the C++11 standard of the key words of the selected keyword is really appropriate and interesting! Well, the gag is here, and now it's time to go back and say std::async.

Why use Std::async instead of thread creation

Std::async is dry, already have td::future, std::p romise and std::p ackaged_task, enough, really want a std::async to join in the fun, std:: Async says it's wronged: I'm not here to join in the fun, I'm here to help. Yes, Std::async is in order to let the user a little bit of a brain, it makes these three objects tacit work. The approximate work process is this: Std::async the asynchronous operation with std::p ackaged_task, and then puts the results of the asynchronous operation into std::p romise, this process is the process of creating the future. Outside again through future.get/wait to get this future result, how, Std::async really is to help, you don't have to think how to use Std::future, std::p romise and std::p ackaged_task, Std::async has done everything for you!

Now look at Std::async's prototype, async (Std::launch::async | std::launch::d eferred, F, args ...), the first parameter is the thread's creation policy, there are two policies, and the default policy is to create the thread immediately:

    • Std::launch::async: Start creating threads when Async is called.
    • Std::launch::d eferred: Lazy load mode creates a thread. When Async is called, the thread is not created until a future get or wait is called.

The second argument is a thread function, and the third parameter is the parameter of the thread function.


Std::async Basic usage:

1std::future<int> f1 =Std::async (Std::launch::async, [] () {2         return 8;3     });4 5cout << F1.Get() << Endl;//Output:86 7std::future<void> F2 =Std::async (Std::launch::async, [] () {8cout <<8<<Endl;9         //return 8;Ten     }); One  AF2.wait ();//Output:8 -  -std::future<int> Future =Std::async (Std::launch::async, [] () { theStd::this_thread::sleep_for (Std::chrono::seconds (3)); -         return 8; -     }); -  +Std::cout <<"waiting...\n"; -      +     //Test12 (); A std::future_status status; atSleep ( the); -      Do { -Status = Future.wait_for (Std::chrono::seconds (1)); -         if(Status = =std::future_status::d eferred) { -Std::cout <<"deferred\n"; -         } in         Else if(Status = =std::future_status::timeout) { -Std::cout <<"timeout\n"; to         } +         Else if(Status = =Std::future_status::ready) { -Std::cout <<"ready!\n"; the         } *} while(Status! =std::future_status::ready); $ Panax NotoginsengStd::cout <<"result is"<< future.Get() <<'\ n';

possible results: Waiting ... timeout timeout ready! result is 8 
Summarize:

Std::async is an asynchronous operation at a higher level, which allows us to easily get asynchronous execution states and results without having to focus on threads creating internal details, and also to specify thread creation policies, which should be used instead of std::async to create a thread, making it the first choice for asynchronous operations.

C++11 Creating an asynchronous program using Std::async

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.