C++11 중 std::packagedtask 사용 설명
10311 단어 C++11std::packaged task
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 이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
어디서나 먹을 수있는 C++ 소프트웨어 엔지니어가되기 위해아래의 책은 숙독하자. 테스트 리팩토링, 좋은 설계란 무엇인가를 배울 수 있습니다. 임베디드 분야의 예를 사용하고 있습니다만, 임베디드를 하지 않는 사람이라도 도움이 되는 내용입니다. C/C++ 언어의 어려운 점은 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.