0Pricing
C++ Academy · บทเรียน

งานอะซิงโครนัสและชนิด 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิดคอร์ูทีน co_await co_yield co_return
  2. การสร้างเจเนอเรเตอร์อย่างง่าย
  3. งานอะซิงโครนัสและชนิด Awaiter
  4. การจัดสรรเฟรมคอร์ูทีน
← กลับไปที่ C++ Academy