packaged_task와 비동기의 차이점은 무엇입니까
C ++ 11의 모델로 작업하는 동안
std::packaged_task<int(int,int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
task(2,3);
std::cout << f.get() << '\n';
과
auto f = std::async(std::launch::async,
[](int a, int b) { return a + b; }, 2, 3);
std::cout << f.get() << '\n';
정확히 같은 일을 할 것입니다. std::async
와 함께 하면 차이가있을 수있는 경우 std::launch::deferred
하나가 큰 실행입니까?
이 두 케이스에서 다른 의미의 차이점은 무엇이며, 더 중요한 것은 무엇입니까?
실제로 방금 제공 한 예는 다음과 같이 다소 긴 기능을 사용하면 차이점을 보여줍니다.
//! sleeps for one second and returns 1
auto sleep = [](){
std::this_thread::sleep_for(std::chrono::seconds(1));
return 1;
};
패키지 된 작업
A packaged_task
는 자체적으로 시작되지도 않습니다.
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\n";
// However, f.get() will be available, since task has already finished.
std::cout << f.get() << std::endl;
std::async
반면 std::async
와 launch::async
는 다른 스레드에서 작업을 실행하려고 시도합니다 .
auto f = std::async(std::launch::async, sleep);
std::cout << "You can see this immediately!\n";
// 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!\n";
약점
그러나 async
모든 것을 사용하기 전에 반환 된 미래에는 특별한 공유 상태가 있으므로 future::~future
차단 해야 합니다.
std::async(do_work1); // ~future blocks
std::async(do_work2); // ~future blocks
/* output: (assuming that do_work* log their progress)
do_work1() started;
do_work1() stopped;
do_work2() started;
do_work2() stopped;
*/
따라서 실제 future
상황이 바뀌면 결과를 유지해야합니다.
{
auto pizza = std::async(get_pizza);
/* ... */
if(need_to_go)
return; // ~future will block
else
eat(pizza.get());
}
이에 대한 자세한 내용은 허브 셔터의 문서를 참조 async
하고~future
, 문제를 설명하고, 스콧 마이어의 std::futures
에서이 std::async
특별하지 않은 게이트웨이를 설명한다. 또한이 동작 은 C ++ 14 이상에서 지정 일반적으로 C ++ 11 구현되었습니다.
추가 차이점
std::async
혹시 사용 하면 더 이상 문구에서 std::packaged_task
사용할 수 있습니다.
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::thread myThread(std::move(task),2,3);
std::cout << f.get() << "\n";
또한를 packaged_task
호출하기 전에를 호출해야합니다 f.get()
. 그렇지 않으면 미래가 준비되지 않으므로 프로그램이 중단됩니다.
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::cout << f.get() << "\n"; // oops!
task(2,3);
TL; DR
std::async
어떤 일을 끝내고 싶고 끝났을 때별로 신경 쓰지 않고 std::packaged_task
다른 스레드로 옮기거나 나중에 호출하기 위해 일을 마무리하고 싶을 때 사용하십시오 . 또는 Christian 을 인용합니다 .
결국 a
std::packaged_task
는 구현을위한 낮은 수준의 기능 일뿐입니다std::async
(이는std::async
같은 다른 낮은 수준의 항목과 함께 사용하는 것보다 더 많은 것을 할 수있는 이유입니다std::thread
). 간단히 말하면 astd::packaged_task
는 a에std::function
연결되어 있고 astd::future
를std::async
감싸고 호출합니다std::packaged_task
(아마도 다른 스레드에서).
패키지 작업 대 비동기
p> 패키지 작업에는 작업[function or function object]
과 미래 / 약속 쌍이 있습니다. 작업이 반환 문을 실행하면됩니다set_value(..)
온packaged_task
의 약속.
a> 주어진 Future, promise 및 package 작업은 스레드에 대해 너무 걱정하지 않고 간단한 작업을 생성 할 수 있습니다 [스레드는 작업을 실행하기 위해 제공하는 것입니다].
그러나 사용할 스레드 수 또는 작업이 현재 스레드 또는 다른 스레드에서 가장 잘 실행되는지 여부 등을 고려해야합니다 async()
. 이러한 결정은 새 스레드를 만들지 또는 이전 스레드를 재활용 할지를 결정 하는 스레드 실행기에 의해 처리 될 수 있습니다. 하나 또는 단순히 현재 스레드에서 작업을 실행합니다. 미래를 반환합니다.
"클래스 템플릿 std :: packaged_task는 호출 가능한 대상 (함수, 람다 식, 바인드 식 또는 다른 함수 개체)을 래핑하여 비동기 적으로 호출 할 수 있도록합니다. 반환 값이나 throw 된 예외는 액세스 할 수있는 공유 상태에 저장됩니다. std :: future 객체를 통해. "
"템플릿 함수 async는 함수 f를 비동기 적으로 (잠재적으로 별도의 스레드에서) 실행하고 결국 해당 함수 호출의 결과를 보유 할 std :: future를 반환합니다."
참고 URL : https://stackoverflow.com/questions/18143661/what-is-the-difference-between-packaged-task-and-async
'IT' 카테고리의 다른 글
Android의 레이아웃 XML에서 app : srcCompat와 android : src의 차이점 (0) | 2020.07.19 |
---|---|
python / matplotlib을 사용하여 3d 거기에 대한 "카메라 위치"를 설정하는 방법은 무엇입니까? (0) | 2020.07.19 |
Visual Studio에서 자동 서식 해제 (0) | 2020.07.19 |
가상 머신을 시작할 때 "VT-x를 사용할 수 없습니다" (0) | 2020.07.19 |
Chrome 개발자 도구에서 데이터 내보내기 (0) | 2020.07.19 |