งานอะซิงโครนัสและชนิด Awaiter
ประกอบงานอะซิงโครนัสด้วยชนิด awaiter และ promise แบบกำหนดเอง
งานอะซิงโครนัสและชนิด Awaiter เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คอร์รูทีนแบบไม่พร้อมกัน
งานแบบไม่พร้อมกันจะหยุดชั่วคราวระหว่างการรับส่งข้อมูล และกลับมาทำงานต่อเมื่อการดำเนินการเสร็จสมบูรณ์ ใช้ co_await ร่วมกับส่วนติดต่อการทำงานแบบไม่พร้อมกัน เพื่อเขียนโค้ดแบบไม่พร้อมกันโดยไม่ต้องใช้การเรียกกลับ
ภาพร่างชนิด Task
Task จะห่อหุ้มคอร์รูทีนแบบไม่พร้อมกัน และรองรับ co_await เพื่อเชื่อมงานต่อกัน
template <typename T>
struct Task {
struct promise_type;
std::coroutine_handle<promise_type> handle;
// ...
};กลไกของ co_await
เมื่อคอมไพเลอร์พบ co_await expr คอมไพเลอร์จะคาดหวังให้ expr เป็นสิ่งที่รอได้ สิ่งที่รอได้มีเมธอดสามอย่าง:
await_ready()— เป็นเท็จเพื่อหยุดชั่วคราว หรือเป็นจริงเพื่อข้ามการหยุดชั่วคราวawait_suspend(handle)— กำหนดว่าจะทำอะไรระหว่างหยุดชั่วคราวawait_resume()— ค่าที่ส่งให้โค้ดผู้เรียก
ตัวอย่างสิ่งที่รอได้: Sleep
สิ่งที่รอได้ซึ่งกำหนดให้ resume หลังจากหน่วงเวลาไปช่วงหนึ่ง
struct Sleep {
std::chrono::milliseconds duration;
bool await_ready() const { return false; }
void await_suspend(std::coroutine_handle<> h) {
std::thread([h, this] {
std::this_thread::sleep_for(duration);
h.resume();
}).detach();
}
void await_resume() {}
};
Task<void> example() {
co_await Sleep{500ms};
std::cout << "after 500ms";
}สิ่งที่รอได้สำหรับ HTTP
ไลบรารีจัดเตรียมสิ่งที่รอได้สำหรับคำขอ HTTP ตัวจับเวลา และการรับส่งข้อมูลกับไฟล์ คุณสามารถนำมาประกอบกันได้เหมือนการเรียกแบบปกติที่ทำงานต่อเนื่อง
Task<std::string> fetch() {
auto data = co_await http_get("/api/data");
co_return data;
}การประกอบงาน
การรอให้งานหนึ่งเสร็จภายในอีกงานหนึ่งจะเชื่อมงานทั้งสองเข้าด้วยกัน งานภายนอกจะหยุดชั่วคราวจนกว่างานภายในจะเสร็จ
Task<int> outer() {
int x = co_await inner_a();
int y = co_await inner_b();
co_return x + y;
}งานแบบขนาน
สำหรับงานแบบไม่พร้อมกันที่ทำงานขนานกัน ให้เริ่มงานโดยยังไม่รอแต่ละงานทันที จากนั้นจึงรอทั้งหมด
Task<int> sum_tasks() {
auto a = inner_a();
auto b = inner_b();
int x = co_await a;
int y = co_await b;
co_return x + y;
}การส่งต่อข้อยกเว้น
ข้อยกเว้นที่เกิดขึ้นภายในงานแบบไม่พร้อมกันสามารถเก็บไว้ใน unhandled_exception ของวัตถุคำสัญญา แล้วโยนซ้ำทางฝั่งที่รอผลได้
การยกเลิก
ไลบรารีมาตรฐานยังไม่มีกลไกพื้นฐานสำหรับการยกเลิก ไลบรารีต่าง ๆ เช่น cppcoro และ boost.cobalt จึงสร้างกลไกของตนเอง โดยทั่วไปใช้โทเค็นการยกเลิกหรือแหล่งสั่งหยุด
การผสานรวมกับ Boost.Asio
Asio รองรับคอร์รูทีนโดยตรง คุณสามารถใช้ co_await กับ async_read, async_write และการดำเนินการลักษณะเดียวกัน ปัจจุบันนี่เป็นวิธีที่สะอาดที่สุดสำหรับการรับส่งข้อมูลแบบไม่พร้อมกันใน C++
ประสิทธิภาพ
การกลับมาทำงานของคอร์รูทีนมีต้นทุนต่ำกว่าการสลับเธรดมาก คอมไพเลอร์มักแทรกโค้ดบางส่วนของเครื่องสถานะไว้ในจุดเรียกใช้ โปรดตรวจวัดประสิทธิภาพเพื่อยืนยันว่าชุดสิ่งที่รอได้ต่อกันของคุณคอมไพล์ได้อย่างราบรื่น
ทิศทางในอนาคต
C++23 เพิ่ม std::generator และการปรับปรุงอีกหลายอย่าง C++26 อาจเพิ่ม std::execution ซึ่งเป็นกรอบการทำงานแบบไม่พร้อมกันที่ครอบคลุมกว่า โดยใช้ตัวส่งและตัวรับ และทำงานร่วมกับคอร์รูทีนได้
ตรวจสอบอย่างรวดเร็ว
ชนิดสิ่งที่รอได้จำเป็นต้องมีฟังก์ชันสมาชิกสามอย่างใด?
สรุปทบทวน
งานแบบไม่พร้อมกันผสาน co_await เข้ากับสิ่งที่รอได้ เพื่อเขียนโค้ดแบบไม่พร้อมกันโดยไม่ต้องใช้การเรียกกลับ สิ่งที่รอได้มี await_ready, await_suspend และ await_resume ไลบรารีต่าง ๆ เช่น cppcoro และ Asio มีชนิดงานและชนิดสิ่งที่รอได้พร้อมใช้ให้แล้ว
คำถามที่พบบ่อย
บทเรียน “งานอะซิงโครนัสและชนิด Awaiter” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “งานอะซิงโครนัสและชนิด Awaiter” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “งานอะซิงโครนัสและชนิด Awaiter”
ประกอบงานอะซิงโครนัสด้วยชนิด awaiter และ promise แบบกำหนดเอง คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “งานอะซิงโครนัสและชนิด Awaiter” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนวคิดคอร์ูทีน co_await co_yield co_return
- การสร้างเจเนอเรเตอร์อย่างง่าย
- งานอะซิงโครนัสและชนิด Awaiter
- การจัดสรรเฟรมคอร์ูทีน