จริงๆแล้วตัวอย่างที่คุณเพิ่งให้แสดงความแตกต่างหากคุณใช้ฟังก์ชันที่ค่อนข้างยาวเช่น
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();
std::cout << "You can see this after 1 second\n";
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";
std::cout << f.get() << "This will be shown after a second!\n";
ข้อเสียเปรียบ
แต่ก่อนที่คุณจะพยายามใช้async
กับทุกสิ่งโปรดจำไว้ว่าอนาคตที่กลับมามีสถานะที่ใช้ร่วมกันพิเศษซึ่งต้องการให้future::~future
บล็อก:
std::async(do_work1);
std::async(do_work2);
ดังนั้นหากคุณต้องการอะซิงโครนัสจริงคุณต้องเก็บสิ่งที่ส่งคืนfuture
ไว้หรือหากคุณไม่สนใจผลลัพธ์หากสถานการณ์เปลี่ยนไป:
{
auto pizza = std::async(get_pizza);
if(need_to_go)
return;
else
eat(pizza.get());
}
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้โปรดดูบทความของ Herb Sutter async
และ~future
ซึ่งอธิบายถึงปัญหาและ Scott Meyer 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";
task(2,3);
TL; ดร
ใช้ในstd::async
กรณีที่คุณต้องการให้บางสิ่งเสร็จสิ้นและไม่สนใจเมื่อทำเสร็จแล้วและstd::packaged_task
หากคุณต้องการสรุปสิ่งต่างๆเพื่อย้ายไปยังเธรดอื่นหรือโทรหาในภายหลัง หรืออ้างถึงคริสเตียน :
ในท้ายที่สุด a std::packaged_task
เป็นเพียงคุณลักษณะระดับล่างสำหรับการใช้งานstd::async
(ซึ่งเป็นเหตุผลว่าทำไมจึงสามารถทำได้มากกว่าstd::async
ถ้าใช้ร่วมกับสิ่งอื่น ๆ ในระดับล่างเช่นstd::thread
) พูดง่ายๆstd::packaged_task
คือ a std::function
เชื่อมโยงกับ a std::future
และstd::async
ตัดและเรียก a std::packaged_task
(อาจอยู่ในเธรดอื่น)