ฉันหมายถึงการเลือกมาตรฐาน POSIX และการเรียกระบบ C API แบบสำรวจความคิดเห็น
ฉันหมายถึงการเลือกมาตรฐาน POSIX และการเรียกระบบ C API แบบสำรวจความคิดเห็น
คำตอบ:
ฉันคิดว่านี่ตอบคำถามของคุณ:
จาก Richard Stevens (rstevens@noao.edu):
ความแตกต่างพื้นฐานคือ fd_set ของ select () เป็นรูปแบบบิตดังนั้นจึงมีขนาดคงที่ เป็นไปได้สำหรับเคอร์เนลที่จะไม่ จำกัด ขนาดนี้เมื่อเคอร์เนลถูกคอมไพล์ทำให้แอปพลิเคชันสามารถกำหนด FD_SETSIZE ให้กับสิ่งที่มันต้องการ (เป็นความคิดเห็นในส่วนหัวของระบบบ่งบอกถึงวันนี้) แต่ใช้งานได้มากกว่า เคอร์เนล 4.4BSD และฟังก์ชันไลบรารี Solaris ทั้งคู่มีข้อ จำกัด นี้ แต่ฉันเห็นว่าตอนนี้ BSD / OS 2.1 ได้รับการเข้ารหัสเพื่อหลีกเลี่ยงข้อ จำกัด นี้ดังนั้นจึงเป็นไปได้เพียงเรื่องเล็ก ๆ ของการเขียนโปรแกรม :-) ใครบางคนควรยื่นรายงานข้อผิดพลาดของ Solaris เกี่ยวกับเรื่องนี้และดูว่ามันได้รับการแก้ไขแล้วหรือไม่
ด้วยโพล () ผู้ใช้จะต้องจัดสรรอาเรย์ของโครงสร้างโพลฟด์และส่งจำนวนรายการในอาเรย์นี้ดังนั้นจึงไม่มีข้อ จำกัด ขั้นพื้นฐาน ในฐานะที่เป็นโน้ตแคสเปอร์ระบบน้อยกว่าจึงมีการสำรวจความคิดเห็น () มากกว่าตัวเลือกดังนั้นระบบหลังจึงพกพาได้มากกว่า นอกจากนี้ด้วยการใช้งานดั้งเดิม (SVR3) คุณไม่สามารถตั้งค่า descriptor เป็น -1 เพื่อบอกเคอร์เนลให้ละเว้นรายการในโครงสร้างของ pollfd ซึ่งทำให้ยากต่อการลบรายการออกจากอาร์เรย์ SVR4 มาถึงสิ่งนี้ โดยส่วนตัวฉันมักจะใช้ select () และไม่ค่อยมีการสำรวจความคิดเห็น () เพราะฉันพอร์ตโค้ดของฉันไปยังสภาพแวดล้อม BSD ด้วย บางคนสามารถเขียนการดำเนินการสำรวจความคิดเห็น () ที่ใช้ select () สำหรับสภาพแวดล้อมเหล่านี้ แต่ฉันไม่เคยเห็นมาก่อน ทั้ง select () และแบบสำรวจ () กำลังได้มาตรฐานโดย POSIX 1003.1g
อีเมลที่อ้างถึงข้างต้นมีอายุอย่างน้อยเท่ากับปี 2001 poll()
คำสั่งอยู่ในขณะนี้ (2017) ได้รับการสนับสนุนในทุกระบบปฏิบัติการที่ทันสมัย - รวมทั้ง BSD ในความเป็นจริงบางคนเชื่อว่าควรจะเลิกใช้select()
ความคิดเห็นเกี่ยวกับปัญหาด้านการพกพาpoll()
ไม่ได้กังวลกับระบบที่ทันสมัยอีกต่อไป นอกจากนี้epoll()
ยังได้รับการพัฒนา (คุณสามารถอ่าน man page ) และยังคงได้รับความนิยมเพิ่มขึ้นอย่างต่อเนื่อง
สำหรับการพัฒนาที่ทันสมัยคุณอาจไม่ต้องการใช้select()
ถึงแม้ว่าจะไม่มีอะไรผิดปกติกับมัน poll()
และมันเป็นวิวัฒนาการที่ทันสมัยยิ่งขึ้นepoll()
ให้คุณสมบัติที่เหมือนกัน (และอื่น ๆ ) select()
โดยไม่ต้องทนทุกข์ทรมานจากข้อ จำกัด ในนั้น
select
หรือpoll
:(
การselect()
เรียกนั้นให้คุณสร้าง bitmasks สามตัวเพื่อทำเครื่องหมายซ็อกเก็ตและตัวอธิบายไฟล์ที่คุณต้องการดูสำหรับการอ่านการเขียนและข้อผิดพลาดจากนั้นระบบปฏิบัติการจะทำเครื่องหมายว่าอันที่จริงแล้วมีกิจกรรมประเภทใด poll()
คุณได้สร้างรายการ descriptor IDs และระบบปฏิบัติการทำเครื่องหมายแต่ละรายการด้วยประเภทของเหตุการณ์ที่เกิดขึ้น
select()
วิธีการค่อนข้าง clunky และไม่มีประสิทธิภาพ
โดยทั่วไปจะมีตัวอธิบายไฟล์ที่เป็นไปได้มากกว่าหนึ่งพันตัวพร้อมใช้งานสำหรับกระบวนการ หากกระบวนการที่ใช้เวลานานมีตัวอธิบายเพียงไม่กี่ตัวที่เปิดอยู่ แต่อย่างน้อยหนึ่งตัวนั้นได้รับการกำหนดเป็นจำนวนสูงselect()
บิตบิทที่ส่งไปจะต้องมีขนาดใหญ่พอที่จะรองรับตัวบ่งชี้ที่สูงที่สุดดังนั้นช่วงทั้งหมดของบิตหลายร้อยบิต จะไม่มีการตั้งค่าว่าระบบปฏิบัติการจะต้องวนซ้ำในทุกการselect()
โทรเพียงเพื่อค้นพบว่าพวกเขาจะไม่มีการตั้งค่า
เมื่อselect()
ส่งคืนผู้เรียกจะต้องวนซ้ำบิตแมปทั้งสามเพื่อตรวจสอบว่าเกิดเหตุการณ์ใดขึ้น ในแอปพลิเคชั่นทั่วไปจำนวนมากเพียงหนึ่งหรือสองตัวอธิบายไฟล์เท่านั้นที่จะได้รับทราฟฟิกใหม่ในเวลาใดก็ตาม แต่ Bitmasks ทั้งสามจะต้องอ่านไปจนจบเพื่อค้นหาตัวบ่งชี้ที่เป็น
เนื่องจากระบบปฏิบัติการส่งสัญญาณคุณเกี่ยวกับกิจกรรมโดยการเขียน bitmasks ใหม่อีกครั้งพวกมันจะถูกทำลายและไม่ถูกทำเครื่องหมายด้วยรายการตัวอธิบายไฟล์ที่คุณต้องการฟังอีกต่อไป คุณต้องสร้าง bitmask ทั้งหมดใหม่จากรายการอื่นที่คุณเก็บไว้ในหน่วยความจำหรือคุณต้องเก็บสำเนาซ้ำของแต่ละ bitmask และmemcpy()
บล็อกของข้อมูลที่อยู่ด้านบนของ bitmasks ที่ถูกทำลายหลังจากการselect()
โทรแต่ละครั้ง
ดังนั้นpoll()
วิธีการใช้งานจะดีกว่ามากเพราะคุณสามารถใช้โครงสร้างข้อมูลเดียวกันซ้ำได้
ในความเป็นจริงpoll()
ได้สร้างแรงบันดาลใจให้กับกลไกอื่นในเคอร์เนล Linux ที่ทันสมัยepoll()
ซึ่งปรับปรุงให้ดียิ่งขึ้นกับกลไกการอนุญาตให้เพิ่มความสามารถในการปรับขนาดได้อีกเนื่องจากเซิร์ฟเวอร์ในปัจจุบันมักต้องการการเชื่อมต่อหลายหมื่นครั้ง นี่คือการแนะนำที่ดีสำหรับความพยายาม:
http://scotdoyle.com/python-epoll-howto.html
ในขณะที่ลิงค์นี้มีกราฟที่ดีแสดงให้เห็นถึงประโยชน์ของepoll()
(คุณจะสังเกตได้ว่าselect()
ณ จุดนี้ถือว่าไม่มีประสิทธิภาพและล้าสมัยมากจนไม่ได้เส้นบนกราฟเหล่านี้!):
http://lse.sourceforge.net/epoll/index.html
อัปเดต:นี่คือคำถาม Stack Overflow อีกคำตอบที่ให้รายละเอียดเพิ่มเติมเกี่ยวกับความแตกต่าง:
ข้อ จำกัด ของการเลือก / การสำรวจกับเครื่องปฏิกรณ์ epoll ใน Twisted
ทั้งสองอย่างนั้นช้าและส่วนใหญ่เหมือนกันแต่มีขนาดและคุณสมบัติแตกต่างกัน!
เมื่อคุณเขียนตัววนซ้ำคุณต้องคัดลอกชุดselect
ทุกครั้ง! ในขณะที่poll
ได้แก้ไขปัญหาประเภทนี้เพื่อให้ได้รหัสที่สวยงาม ข้อแตกต่างอีกประการหนึ่งคือpoll
สามารถจัดการตัวอธิบายไฟล์ (FD) มากกว่า 1024 ตัวตามค่าเริ่มต้น poll
สามารถจัดการเหตุการณ์ต่าง ๆ เพื่อให้โปรแกรมอ่านง่ายขึ้นแทนที่จะมีตัวแปรจำนวนมากเพื่อจัดการงานประเภทนี้ การดำเนินงานในpoll
และselect
เป็นเชิงเส้นและช้าเพราะมีการตรวจสอบจำนวนมาก