C++11 Multithreading (vi): " detailed two: std::p ackaged_task Introduction" __c++

Source: Internet
Author: User
Tags wrapper
Reference connection:
http://www.cnblogs.com/haippy/p/3279565.html a good blog

Http://www.cplusplus.com/reference/future/future/cplusplus official website


Directory
1.STD::p ackaged_task Introduction
2.STD::p Ackaged_task Constructor
3.STD::p ackaged_task::valid Introduction
4.STD::p ackaged_task::get_future Introduction
5.STD::p ackaged_task::operator () (Args ... Args) Introduction
6.STD::p ackaged_task::make_ready_at_thread_exit Introduction
7.STD::p ackaged_task::reset () Introduction
8.STD::p ackaged_task::swap () Introduction


1.STD::p ackaged_task Introduction
std::p Ackaged_task Wraps a callable object and allows the result of the callable object to be fetched asynchronously, in the sense of the wrapper callable object, std::p ackaged_task is similar to std::function, except std:: Packaged_task passes the execution result of the callable object that it wraps to a Std::future object, which typically acquires STD in another thread::p The execution result of the Ackaged_task task).


std::p The Ackaged_task object contains two basic elements internally:
One, the wrapped task (stored task) is a callable object, such as a function pointer, a member function pointer, or a function object;
Shared state, which is used to save the return value of a task, can achieve the effect of asynchronous access to a shared state by std::future the object.


The Std::future object associated with the shared state can be obtained through std::p ackged_task::get_future. After the function is called, two objects share the same shared state, as explained below:
std::p Ackaged_task object is an asynchronous Provider that, at some point, sets the value of the shared state by invoking the wrapped task.
The Std::future object is an asynchronous return object that obtains the value of the shared state and, of course, waits for the shared status flag to become ready when necessary.
std: The lifecycle of the shared state of the:p Ackaged_task continues until the last object associated with it is released or destroyed.


The following is a small example of the use of std::p ackaged_task:
#include <iostream>//Std::cout
#include <future>/std::p ackaged_task, Std::future
#include <chrono>//Std::chrono::seconds
#include <thread>//Std::thread, Std::this_thread::sleep_for


Count down taking a second to each value:
int countdown (int from, int to)
{

for (int i=from; i!=to; i.)

{std::cout << i << ' \ n ';
Std::this_thread::sleep_for (Std::chrono::seconds (1));
}
Std::cout << "finished!\n";
return from-to;
}


int main ()
{
std::p ackaged_task<int (Int,int) > Task (Countdown); Set Packaged_task
std::future<int> ret = Task.get_future (); Gets the future object associated with the Packaged_task share state.


Std::thread th (Std::move (Task), 10, 0); Create a new thread to complete the Count task.


int value = Ret.get (); Wait for the task to complete and get the result.


Std::cout << "The countdown lasted for" << value << "seconds.\n";


Th.join ();
return 0;
}


2.STD::p Ackaged_task Constructor
std::p The Ackaged_task constructor has a total of 5 forms, but the copy construct has been disabled.
The following is a brief introduction to the semantics of several of these constructors:
A. The default constructor initializes an empty shared state, and the Packaged_task object has no wrapper task.
B. Initializes a shared state, and the wrapped task is specified by the parameter FN.
C. A constructor with a custom memory allocator, similar to the default constructor, but uses a custom allocator to assign a shared state.
D. copy constructor, disabled.
E. Move the constructor.
Similar to std::p romise, std::p ackaged_task also disables normal assignment operations, allowing only move assignment operations.
The following examples describe the use of various constructors:
#include <iostream>//Std::cout
#include <utility>//Std::move
#include <future>/std::p ackaged_task, Std::future
#include <thread>//Std::thread


int main ()
{
std::p ackaged_task<int (int) > foo; The default constructor.


Initializes a Packaged_task object using a lambda expression.
std::p ackaged_task<int (int) > bar ([] (int x) {return x*2;});


foo = Std::move (bar); The move-assignment operation is also a new feature in the c++11.


Gets the future object associated with the Packaged_task share state.
std::future<int> ret = Foo.get_future ();


Std::thread (Std::move foo). Detach (); Produces a thread that invokes the wrapped task.


int value = Ret.get (); Wait for the task to complete and get the result.
Std::cout << "The Double is" << value << ". \ n";


return 0;
}


3.STD::p ackaged_task::valid Introduction
Checks whether the current packaged_task is associated with a valid shared state, and returns false for the Packaged_task object generated by the default constructor, unless a move assignment operation or a swap is performed in the middle.


Take a look at the following example:
#include <iostream>//Std::cout
#include <utility>//Std::move
#include <future>/std::p ackaged_task, Std::future
#include <thread>//Std::thread


Starts an int (int) packaged_task in a new thread.
Std::future<int> Launcher (std::p ackaged_task<int (int) >& tsk, int arg)
{
if (Tsk.valid ()) {
std::future<int> ret = Tsk.get_future ();
Std::thread (Std::move (tsk), Arg). Detach ();
return ret;
}
else return std::future<int> ();
}


int main ()
{
std::p ackaged_task<int (int) > Tsk ([] (int x) {return x*2;});


Std::future<int> fut = launcher (tsk,25);


Std::cout << "The Double is" << fut.get () << ". \ n";


return 0;
}


4.STD::p ackaged_task::get_future Introduction
Returns a future object that is associated with the shared state of the Packaged_task object. The returned future object can obtain a value or exception that is set by another thread on the shared state of the Packaged_task object.


Take a look at the example (in fact, I've already mentioned the get_future example):
#include <iostream>//Std::cout
#include <utility>//Std::move
#include <future>/std::p ackaged_task, Std::future
#include <thread>//Std::thread


int main ()
{
std::p ackaged_task<int (int) > Tsk ([] (int x) {return x * 3;}); Package task


Std::future<int> fut = tsk.get_future (); Gets the future object.


Std::thread (Std::move (TSK), detach (); Generate a new thread and invoke Packaged_task.


int value = Fut.get (); Wait for the task to complete and get the result.


Std::cout << "The triple of is" << value << ". \ n";


return 0;
}


5.STD::p ackaged_task::operator () (Args ... Args) Introduction

Invokes the object wrapped by the Packaged_task object (usually a function pointer, function object, lambda expression, and so on), and the passed-in parameter is args. Calling this function typically occurs in two different situations:
If the object wrapped by Packaged_task is successfully invoked, the return value (if the wrapped object has a return value) is saved in the shared state of Packaged_task.
If the object wrapped by the call to Packaged_task fails and an exception is thrown, the exception is also saved in the shared state of Packaged_task.
Both of these situations make the flag of the shared state become ready, so other threads waiting for the shared state can get the value or exception of the shared state and continue execution.
The value of the shared state can be obtained by calling get on the future object (obtained by get_future).
Because the wrapped task is specified at the Packaged_task construct, the effect of the call to operator () is determined by the callable object specified when the Packaged_task object was constructed:
A. If the wrapped task is a function pointer or function object, call std::p ackaged_task::operator () simply passes the parameter to the wrapped object.
B. If the wrapped task is a pointer to a non-static member function of a class, then the first parameter of std::p ackaged_task::operator () should be specified as the object to which the member function is invoked, and the remaining arguments as arguments to the member function.
C. If the wrapped task is a non-static member variable that points to a class, then std::p ackaged_task::operator () only allows a single parameter.


6.STD::p ackaged_task::make_ready_at_thread_exit Introduction
The function invokes the wrapped task and passes parameters to the task, similar to the std::p ackaged_task operator () member function. However, unlike the operator () function, Make_ready_at_thread_exit does not immediately set the flag for the shared state to be ready, but rather a flag that sets the shared state when the thread exits.
If the future object associated with the Packaged_task shared state waits at Future::get, the current Future::get call is blocked until the thread exits. And once the thread exits, the future::get call continues execution, or throws an exception.
Note that the function has set a value for the Promise share state, and if there are other settings or modifications to the values of the shared state before the thread ends, Future_error (promise_already_satisfied) is thrown.

7.STD::p ackaged_task::reset () Introduction
Resets the shared state of the packaged_task, but retains the previously wrapped task. Take a look at the example, in which Packaged_task has been reused several times: (the following code runs the wrong time, not resolved)
#include <iostream>//Std::cout
#include <utility>//Std::move
#include <future>/std::p ackaged_task, Std::future
#include <thread>//Std::thread


A simple task:
int triple (int x) {return x*3;}


int main ()
{
std::p ackaged_task<int (int) > Tsk (Triple); Package task




Std::future<int> fut = tsk.get_future ();
Std::thread (Std::move (TSK), detach ();
Std::cout << "The triple of" << Fut.get () << ". \ n";




Re-use same Task object:
Tsk.reset ();
FUT = Tsk.get_future ();
Std::thread (Std::move (TSK), detach ();
Std::cout << "thre triple of" << Fut.get () << ". \ n";


return 0;
}


8.STD::p ackaged_task::swap () Introduction
Swap the shared state of the packaged_task.

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.