สำหรับซ็อกเก็ตจำนวนน้อยมาก (แน่นอนแตกต่างกันไปขึ้นอยู่กับฮาร์ดแวร์ของคุณ แต่เรากำลังพูดถึงบางอย่างตามลำดับ 10 หรือน้อยกว่า) เลือกสามารถเอาชนะ epoll ในการใช้หน่วยความจำและความเร็วรันไทม์ แน่นอนว่าสำหรับซ็อกเก็ตจำนวนน้อยกลไกทั้งสองนั้นเร็วมากจนคุณไม่สนใจเกี่ยวกับความแตกต่างนี้ในกรณีส่วนใหญ่
แม้ว่าการชี้แจงอย่างใดอย่างหนึ่ง ทั้ง select และ epoll scale linearly แม้ว่าความแตกต่างอย่างมากก็คือ APIs ที่หันหน้าเข้าหาผู้ใช้มีความซับซ้อนที่ขึ้นอยู่กับสิ่งต่างๆ ค่าใช้จ่ายของการselect
โทรจะประมาณตามค่าของตัวอธิบายไฟล์ที่มีหมายเลขสูงสุดที่คุณส่งผ่าน หากคุณเลือก fd เดียว 100 ก็จะแพงกว่าการเลือก fd ตัวเดียว 50 ประมาณสองเท่าการเพิ่ม fds ให้ต่ำกว่าค่าสูงสุดนั้นไม่เสียค่าใช้จ่ายดังนั้นในทางปฏิบัติจึงค่อนข้างซับซ้อนกว่านี้เล็กน้อย เป็นค่าประมาณแรกที่ดีสำหรับการใช้งานส่วนใหญ่
ค่าใช้จ่ายของ epoll ใกล้เคียงกับจำนวนตัวอธิบายไฟล์ที่มีเหตุการณ์อยู่ หากคุณกำลังตรวจสอบตัวอธิบายไฟล์ 200 ไฟล์ แต่มีเพียง 100 ตัวเท่านั้นที่มีเหตุการณ์ในนั้นแสดงว่าคุณ (โดยประมาณมาก) จ่ายเงินสำหรับตัวอธิบายไฟล์ที่ใช้งาน 100 ไฟล์เท่านั้น นี่คือจุดที่ epoll มีแนวโน้มที่จะนำเสนอข้อได้เปรียบที่สำคัญอย่างหนึ่งมากกว่าการเลือก หากคุณมีลูกค้านับพันรายที่ส่วนใหญ่ไม่ได้ใช้งานเมื่อคุณใช้ select คุณจะยังคงจ่ายเงินให้กับลูกค้าทั้งหมดหนึ่งพันราย อย่างไรก็ตามด้วย epoll ก็เหมือนกับว่าคุณมีเพียงไม่กี่ชิ้นเท่านั้นคุณจะจ่ายเฉพาะรายการที่มีการใช้งานในช่วงเวลาใดเวลาหนึ่ง
ทั้งหมดนี้หมายความว่า epoll จะนำไปสู่การใช้งาน CPU น้อยลงสำหรับภาระงานส่วนใหญ่ เท่าที่การใช้งานหน่วยความจำดำเนินไปมันก็ค่อนข้างแย่ select
จัดการเพื่อแสดงข้อมูลที่จำเป็นทั้งหมดในรูปแบบที่กะทัดรัดมาก (หนึ่งบิตต่อตัวอธิบายไฟล์) และข้อ จำกัด FD_SETSIZE (โดยทั่วไปคือ 1024) เกี่ยวกับจำนวนตัวอธิบายไฟล์ที่คุณสามารถใช้โดยselect
หมายความว่าคุณจะไม่ใช้จ่ายเกิน 128 ไบต์สำหรับชุด fd ทั้งสามชุดที่คุณสามารถใช้ได้select
(อ่านเขียนข้อยกเว้น) เมื่อเทียบกับสูงสุด 384 ไบต์แล้ว epoll ก็เหมือนกับหมู ตัวอธิบายไฟล์แต่ละตัวจะแสดงด้วยโครงสร้างแบบหลายไบต์ อย่างไรก็ตามในแง่ที่แน่นอนมันจะยังไม่ใช้หน่วยความจำมากนัก คุณสามารถแสดงตัวอธิบายไฟล์จำนวนมากได้ในไม่กี่สิบกิโลไบต์ (ฉันคิดว่าประมาณ 20k ต่อ 1,000 ตัวอธิบายไฟล์) และคุณยังสามารถโยนความจริงที่ว่าคุณต้องใช้จ่ายทั้งหมด 384 ไบต์select
หากคุณต้องการตรวจสอบตัวอธิบายไฟล์เพียงไฟล์เดียว แต่ค่าของมันเป็น 1024 ส่วน epoll คุณจะใช้จ่ายเพียง 20 ไบต์เท่านั้น ถึงกระนั้นตัวเลขทั้งหมดนี้ก็ค่อนข้างเล็กจึงไม่ได้สร้างความแตกต่างมากนัก
นอกจากนี้ยังมีประโยชน์อื่น ๆ ของ epoll ซึ่งบางทีคุณอาจทราบอยู่แล้วว่าไม่ จำกัด เฉพาะคำอธิบายไฟล์ FD_SETSIZE คุณสามารถใช้เพื่อตรวจสอบตัวอธิบายไฟล์ได้มากเท่าที่คุณมี และหากคุณมีตัวอธิบายไฟล์เพียงตัวเดียว แต่ค่าของไฟล์นั้นมากกว่า FD_SETSIZE epoll ก็ใช้ได้เช่นกัน แต่select
ไม่มี
สุ่มฉันยังเพิ่งค้นพบหนึ่งอุปสรรคเล็กน้อยepoll
เมื่อเทียบกับหรือselect
poll
แม้ว่า API ทั้งสามตัวนี้จะไม่รองรับไฟล์ปกติ (เช่นไฟล์ในระบบไฟล์) select
และpoll
นำเสนอการขาดการสนับสนุนนี้เช่นการรายงานตัวอธิบายที่อ่านได้และเขียนได้เสมอ สิ่งนี้ทำให้ไม่เหมาะสำหรับ I / O ระบบไฟล์ที่ไม่มีการปิดกั้นที่มีความหมายใด ๆ โปรแกรมที่ใช้select
หรือpoll
และบังเอิญพบตัวอธิบายไฟล์จากระบบไฟล์อย่างน้อยก็จะยังคงทำงานต่อไป (หรือหากล้มเหลวก็จะไม่เป็นเพราะ ของselect
หรือpoll
) แม้ว่าอาจจะไม่ได้มีประสิทธิภาพที่ดีที่สุด
ในทางกลับกันepoll
จะล้มเหลวอย่างรวดเร็วโดยมีข้อผิดพลาด ( EPERM
เห็นได้ชัด) เมื่อถูกขอให้ตรวจสอบตัวอธิบายไฟล์ดังกล่าว พูดอย่างเคร่งครัดนี่แทบจะไม่ถูกต้อง เป็นเพียงการส่งสัญญาณว่าไม่มีการสนับสนุนอย่างชัดเจน โดยปกติฉันจะปรบมือให้กับเงื่อนไขความล้มเหลวอย่างชัดเจน แต่สิ่งนี้ไม่มีเอกสาร (เท่าที่ฉันสามารถบอกได้) และส่งผลให้แอปพลิเคชันเสียโดยสิ้นเชิงแทนที่จะเป็นแอปพลิเคชันที่ทำงานด้วยประสิทธิภาพที่ลดลงเท่านั้น
ในทางปฏิบัติสถานที่เดียวที่ฉันเห็นสิ่งนี้เกิดขึ้นคือเมื่อโต้ตอบกับ stdio ผู้ใช้อาจเปลี่ยนเส้นทาง stdin หรือ stdout จาก / ไปยังไฟล์ปกติ ในขณะที่ก่อนหน้านี้ stdin และ stdout จะเป็นไปป์ - รองรับโดย epoll ได้ดี - จากนั้นก็กลายเป็นไฟล์ปกติและ epoll ก็ล้มเหลวเสียงดังทำให้แอปพลิเคชันเสียหาย
poll
เพื่อความสมบูรณ์?