ฉันกำลังดูการสนทนานี้เกี่ยวกับการใช้ Async IO ใน Rust และ Carl กล่าวถึงแบบจำลองที่มีศักยภาพสองแบบ ความพร้อมและความสำเร็จ
โมเดลความพร้อม:
- คุณบอกเคอร์เนลที่คุณต้องการอ่านจากซ็อกเก็ต
- ทำสิ่งอื่นเพื่อสักครู่ ...
- เคอร์เนลจะบอกคุณเมื่อซ็อกเก็ตพร้อม
- คุณอ่าน (เติมบัฟเฟอร์)
- ทำสิ่งที่คุณต้องการ
- ฟรีบัฟเฟอร์ (เกิดขึ้นโดยอัตโนมัติด้วยสนิม)
เสร็จสิ้นรูปแบบ:
- คุณจัดสรรบัฟเฟอร์เพื่อให้เคอร์เนลเติม
- ทำสิ่งอื่นเพื่อสักครู่ ...
- เคอร์เนลจะบอกคุณเมื่อบัฟเฟอร์เต็ม
- ทำสิ่งที่คุณต้องการด้วยข้อมูล
- ฟรีบัฟเฟอร์
คาร์ลในตัวอย่างของการใช้รูปแบบการเตรียมความพร้อมที่คุณสามารถย้ำกว่าซ็อกเก็ตพร้อมเติมและพ้นบัฟเฟอร์ทั่วโลกซึ่งจะทำให้มันดูเหมือนมันจะใช้มากหน่วยความจำน้อย
ตอนนี้สมมติฐานของฉัน:
ภายใต้ประทุน (ในพื้นที่เคอร์เนล) เมื่อซ็อกเก็ตถูกกล่าวว่าเป็น "พร้อม" ข้อมูลมีอยู่แล้ว มันเข้ามาในซ็อกเก็ตผ่านเครือข่าย (หรือจากที่ใดก็ได้) และระบบปฏิบัติการนั้นก็เก็บข้อมูลไว้
มันไม่เหมือนกับว่าการจัดสรรหน่วยความจำอย่างน่าอัศจรรย์ไม่ได้เกิดขึ้นในโมเดลความพร้อม มันเป็นเพียงแค่ระบบปฏิบัติการที่เป็นนามธรรมจากคุณ ในรูปแบบเสร็จสมบูรณ์ระบบปฏิบัติการจะขอให้คุณจัดสรรหน่วยความจำก่อนที่ข้อมูลจะไหลเข้ามาและเห็นได้ชัดว่าเกิดอะไรขึ้น
นี่คือโมเดลการเตรียมพร้อมในการแก้ไขของฉัน:
- คุณบอกเคอร์เนลที่คุณต้องการอ่านจากซ็อกเก็ต
- ทำสิ่งอื่นเพื่อสักครู่ ...
- การแก้ไข: ข้อมูลเข้าสู่ระบบปฏิบัติการ (บางที่ในหน่วยความจำเคอร์เนล)
- เคอร์เนลบอกคุณซ็อกเก็ตพร้อม
- คุณอ่าน (กรอกบัฟเฟอร์อื่นแยกต่างหากจากบัฟเฟอร์เคอร์เนลในต่างประเทศ (หรือคุณได้รับตัวชี้ไป?))
- ทำสิ่งที่คุณต้องการ
- ฟรีบัฟเฟอร์ (เกิดขึ้นโดยอัตโนมัติด้วยสนิม)
/ สมมติฐานของฉัน
ฉันชอบที่จะทำให้โปรแกรมพื้นที่ผู้ใช้มีขนาดเล็ก แต่ฉันแค่ต้องการชี้แจงเกี่ยวกับสิ่งที่ในความเป็นจริงเกิดขึ้นที่นี่ ฉันไม่เห็นว่ารุ่นหนึ่งจะใช้หน่วยความจำน้อยลงหรือสนับสนุนระดับ IO พร้อมกันในระดับที่สูงขึ้น ฉันชอบที่จะได้ยินความคิดและคำอธิบายที่ลึกกว่านี้