จริงๆแล้วตัวอย่างที่คุณเพิ่งให้แสดงความแตกต่างหากคุณใช้ฟังก์ชันที่ค่อนข้างยาวเช่น
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(อาจอยู่ในเธรดอื่น)