C++11 중 std::packagedtask 사용 설명

C++11 의 std::packagedtask 는 템 플 릿 클래스 입 니 다.std::packaged_task 는 비동기 적 으로 호출 할 수 있 도록 대상(함수,lambda 표현 식,bid 표현 식,함수 대상)을 포장 합 니 다.반환 값 이나 던 진 이상 은 std:future 대상 을 통 해 접근 할 수 있 는 공유 상태 에 저 장 됩 니 다.
std::packaged_task 는 std:function 과 유사 하지만 그 결 과 를 std:future 대상 에 게 자동 으로 전달 합 니 다.
std::packaged_task 대상 내부 에는 두 가지 요소 가 포함 되 어 있 습 니 다.(1)저 장 된 작업(stored task)은 호출 가능 한 대상(예 를 들 어 함수 포인터,구성원 또는 함수 대상 의 포인터)(A stored task,which is some callable object(such as a function pointer,pointer to member or function object)입 니 다.(2).공유 상 태 는 저 장 된 작업(stored task)을 호출 한 결 과 를 저장 할 수 있 으 며 std::future 를 통 해 비동기 접근(A shared state,which is able to store the results of calling the stored task and be accessed asynchronously through a future)을 할 수 있 습 니 다.
std::packaged 호출task 의 getfuture 멤버 들 은 std::future 대상 과 공 유 됩 니 다.호출 후 두 대상 은 같은 공유 상 태 를 공유 합 니 다:(1).std::packagedtask 대상 은 비동기 공급 자(asynchronous provider)입 니 다.저 장 된 작업(stored task)을 호출 하여 어느 순간 공유 상 태 를 준비 해 야 합 니 다.(2).std::future 대상 은 비동기 반환 대상 으로 공유 상태의 값 을 검색 하고 필요 할 때 준 비 를 기다 릴 수 있 습 니 다.
공유 상태의 생존 기간 은 적어도 그 와 관련 된 마지막 대상 이 석방 되 거나 소 각 될 때 까지 지속 해 야 한다.
std::packaged_task 는 스스로 시작 하지 않 습 니 다.호출 해 야 합 니 다(A packagedtask won't start on it's own, you have to invoke it)。
std::future 소개 참고:https://www.jb51.net/article/179229.htm
템 플 릿 클래스 std::packagedtask 멤버 함수 포함:
1.구조 함수:(1).기본 구조 함수:공유 상태 가 없 는 저장 작업(no shared state and no stored task)에서 대상 을 초기 화 합 니 다.(2).initialization constructor:이 대상 은 공유 상 태 를 가지 고 있 으 며 저 장 된 작업 은 fn 에서 초기 화 됩 니 다.(3). initialization constructor with allocator。(4).복사 구 조 를 사용 하지 않 습 니 다.(5).이동 구 조 를 지원 합 니 다.
2.석조 함수:(1).(abandon)공유 상 태 를 포기 하고 packaged 를 소각 합 니 다.task 대상.2).다른 future 대상 이 같은 공유 상태 에 연결 되 어 있 으 면 공유 상태 자체 가 소각 되 지 않 습 니 다.(3).packagedtask 대상 이 공유 상태 가 준비 되 기 전에 소각 되면 공유 상태 가 자동 으로 준비 되 고 std::future 를 포함 합 니 다.error 형식의 이상.
3. get_future 함수:(1).packaged 를 되 돌려 줍 니 다.task 대상 의 공유 상태 와 연 결 된 std::future 대상.(2).저 장 된 작업 이 호출 되면 돌아 오 는 std::future 대상 은 packaged 에 접근 할 수 있 습 니 다.task 대상 이 공유 상태 에서 설정 한 값 이나 이상 입 니 다.(3)..패키지 마다task 공유 상 태 는 std::future 대상 검색(Only one future object can be retrieved for each packagedtask shared state)。(4).이 함 수 를 호출 하면 packagedtask 는 언제 쯤 공유 상 태 를 준비 해 야 합 니 다.(저 장 된 작업 을 호출 하여)그렇지 않 으 면 소각 후 자동 으로 준비 되 고 std::future 를 포함 합 니 다.error 형식의 이상.
4. make_ready_at_thread_exit 함수:스 레 드 가 종료 되 었 을 때 만 공유 상태 ready 를 호출 이 완료 되 었 을 때 바로 ready 가 아 닙 니 다.
5.operator=:(1).복사 할당 을 사용 하지 않 습 니 다.(2).이동 할당 을 지원 합 니 다.
6. operator():(1).call stored task。(2).저장 작업 의 호출 이 성공 적 으로 완료 되 거나 이상 을 던 지면 되 돌아 오 는 값 이나 캡 처 된 이상 이 공유 상태 에 저장 되 고 공유 상태 가 준비 되 어 있 습 니 다(현재 기다 리 고 있 는 모든 스 레 드 를 차단 해제 합 니 다).
7.reset 함수:(1).같은 저 장 된 작업 을 유지 하 는 동시에 새로운 공유 상태 로 대상 을 초기 화 합 니 다.(2).저 장 된 작업 을 다시 호출 할 수 있 습 니 다.(3).대상 과 연 결 된 이전의 공유 상태 가 포기 되 었 습 니 다(마치 packagedtask 가 소 각 된 것 과 같다.4).내부 에서 이 함수 의 행 위 는 새로운 구 조 를 가 진 packaged 를 이동 하 는 것 과 같 습 니 다.task 와 같이(내부 적 으로,함 수 는 새로 구 성 된 packaged 를 move-assigned 한 것 처럼 동작 합 니 다.task (with its stored task as argument))。
8.swap 함수/비 구성원 템 플 릿 함수 swap:공유 상태 와 저 장 된 작업(stored task)을 교환 합 니 다.
9.유효한 함수:packaged 검사task 대상 이 공유 상태 가 있 는 지 여부 입 니 다.
상세 한 용법 은 아래 의 테스트 코드 를 볼 수 있 습 니 다.다음은 다른 글 에서 copy 의 테스트 코드 입 니 다.부분 은 조정 되 었 고 상세 한 내용 은 대응 하 는 reference 를 참고 할 수 있 습 니 다.

#include "future.hpp"
#include <iostream>
#include <future>
#include <chrono>
#include <utility>
#include <thread>
#include <functional>
#include <memory>
#include <exception> 
#include <numeric>
#include <vector>
#include <cmath>
#include <string>
 
namespace future_ {
 
///////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/future/packaged_task/
int test_packaged_task_1()
{
 
{ // constructor/get_future/operator=/valid
 std::packaged_task<int(int)> foo; // default-constructed
 std::packaged_task<int(int)> bar([](int x) { return x * 2; }); // initialized
 
 foo = std::move(bar); // move-assignment
 std::cout << "valid: " << foo.valid() << "
"; std::future<int> ret = foo.get_future(); // get future std::thread(std::move(foo), 10).detach(); // spawn thread and call task int value = ret.get(); // wait for the task to finish and get result std::cout << "The double of 10 is " << value << ".
"; } { // reset/operator() std::packaged_task<int(int)> tsk([](int x) { return x * 3; }); // package task std::future<int> fut = tsk.get_future(); tsk(33); std::cout << "The triple of 33 is " << fut.get() << ".
"; // re-use same task object: tsk.reset(); fut = tsk.get_future(); std::thread(std::move(tsk), 99).detach(); std::cout << "Thre triple of 99 is " << fut.get() << ".
"; } { // constructor/get_future auto countdown = [](int from, int to) { for (int i = from; i != to; --i) { std::cout << i << '
'; std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cout << "Lift off!
"; return from - to; }; std::packaged_task<int(int, int)> tsk(countdown); // set up packaged_task std::future<int> ret = tsk.get_future(); // get future std::thread th(std::move(tsk), 5, 0); // spawn thread to count down from 5 to 0 int value = ret.get(); // wait for the task to finish and get result std::cout << "The countdown lasted for " << value << " seconds.
"; th.join(); } return 0; } /////////////////////////////////////////////////////////// // reference: https://en.cppreference.com/w/cpp/thread/packaged_task int test_packaged_task_2() { { // 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() << '
'; } { // bind std::packaged_task<int()> task(std::bind([](int x, int y) { return std::pow(x, y); }, 2, 11)); std::future<int> result = task.get_future(); task(); std::cout << "task_bind:\t" << result.get() << '
'; } { // thread std::packaged_task<int(int, int)> task([](int x, int y) { return std::pow(x, y); }); 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() << '
'; } return 0; } /////////////////////////////////////////////////////////// // reference: https://thispointer.com/c11-multithreading-part-10-packaged_task-example-and-tutorial/ struct DBDataFetcher { std::string operator()(std::string token) { // Do some stuff to fetch the data std::string data = "Data From " + token; return data; } }; int test_packaged_task_3() { // Create a packaged_task<> that encapsulated a Function Object std::packaged_task<std::string(std::string)> task(std::move(DBDataFetcher())); // Fetch the associated future<> from packaged_task<> std::future<std::string> result = task.get_future(); // Pass the packaged_task to thread to run asynchronously std::thread th(std::move(task), "Arg"); // Join the thread. Its blocking and returns when thread is finished. th.join(); // Fetch the result of packaged_task<> i.e. value returned by getDataFromDB() std::string data = result.get(); std::cout << data << std::endl; return 0; } /////////////////////////////////////////////////////////// // reference: https://stackoverflow.com/questions/18143661/what-is-the-difference-between-packaged-task-and-async int test_packaged_task_4() { // sleeps for one second and returns 1 auto sleep = []() { std::this_thread::sleep_for(std::chrono::seconds(1)); return 1; }; { // std::packaged_task // >>>>> A packaged_task won't start on it's own, you have to invoke it std::packaged_task<int()> task(sleep); auto f = task.get_future(); task(); // invoke the function // You have to wait until task returns. Since task calls sleep // you will have to wait at least 1 second. std::cout << "You can see this after 1 second
"; // However, f.get() will be available, since task has already finished. std::cout << f.get() << std::endl; } { // std::async // >>>>> On the other hand, std::async with launch::async will try to run the task in a different thread : auto f = std::async(std::launch::async, sleep); std::cout << "You can see this immediately!
"; // However, the value of the future will be available after sleep has finished // so f.get() can block up to 1 second. std::cout << f.get() << "This will be shown after a second!
"; } return 0; } } // namespace future_
GitHub: https://github.com/fengbingchun/Messy_Test
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기