ฟังเหตุการณ์ทำงานอย่างไร


125

ในช่วงหนึ่งของการบรรยายของฉันในวันนี้เกี่ยวกับ Unity เราได้พูดคุยอัปเดตตำแหน่งผู้เล่นของเราโดยการตรวจสอบทุกเฟรมหากผู้ใช้กดปุ่มลง มีคนบอกว่านี่ไม่มีประสิทธิภาพและเราควรใช้ฟังเหตุการณ์แทน

คำถามของฉันคือไม่คำนึงถึงภาษาการเขียนโปรแกรมหรือสถานการณ์ที่ใช้ในการฟังเหตุการณ์ทำงานอย่างไร

สัญชาตญาณของฉันจะถือว่าผู้ฟังเหตุการณ์ตรวจสอบอย่างต่อเนื่องว่าเหตุการณ์ถูกยิงหรือไม่ความหมายในสถานการณ์ของฉันมันจะไม่แตกต่างจากการตรวจสอบทุกเฟรมหากเหตุการณ์นั้นถูกไล่ออก

จากการอภิปรายในชั้นเรียนดูเหมือนว่าผู้ฟังเหตุการณ์จะทำงานในลักษณะที่แตกต่างออกไป

ฟังเหตุการณ์ทำงานอย่างไร


34
ฟังเหตุการณ์ไม่ได้ตรวจสอบเลย มันจะถูกเรียกเมื่อเหตุการณ์ที่มันเป็น "การฟัง" ที่จะยิง
Robert Harvey

13
ใช่ แต่มันฟัง "อย่างไร" จะไม่ตรวจสอบอย่างต่อเนื่องใช่หรือไม่
Gary Holiday

28
Nope "Event Listener" น่าจะเป็นคำที่ไม่ถูกต้อง จริงๆแล้วมันไม่ได้ "ฟัง" เลย ผู้ฟังเหตุการณ์ทั้งหมดรอที่จะถูกเรียกโดยเหตุการณ์เมื่อมันเริ่มขึ้นเหมือนกับวิธีอื่น ๆ จนกว่าจะได้รับการเรียกแบบนี้มันไม่ทำอะไรเลย
Robert Harvey

28
ทุกครั้งที่คุณตรวจสอบเพื่อดูว่ามีการกดปุ่มหรือไม่ ตัวจัดการเหตุการณ์ (ผู้ฟัง) จ่ายเงินให้คุณเฉพาะเมื่อกดปุ่มจริงเท่านั้น
Robert Harvey

45
@RobertHarvey - ไม่จำเป็นว่า "ผู้ฟัง" ยังคงต้องการการสำรวจในระดับที่ต่ำกว่า คุณเพียงแค่เพิ่มความซับซ้อนจากเลเยอร์โค้ดของคุณเองลึกลงไปจนถึงการขัดจังหวะของฮาร์ดแวร์หรืออะไรก็ตาม และใช่มันมักจะมีประสิทธิภาพมากกว่า แต่ไม่ใช่เพราะการฟังดีกว่าการเลือกตั้งเพราะการลงคะแนนในระดับต่ำกว่ามีประสิทธิภาพมากกว่าการลงคะแนนจาก C # และ 15 ชั้นที่เป็นนามธรรมระหว่างคุณและฮาร์ดแวร์
Davor Ždralo

คำตอบ:


140

ซึ่งแตกต่างจากตัวอย่างการสำรวจที่คุณให้ไว้ (โดยที่ปุ่มถูกเลือกทุกเฟรม) ผู้ฟังเหตุการณ์จะไม่ตรวจสอบว่ากดปุ่มเลยหรือไม่ แต่มันจะถูกเรียกเมื่อกดปุ่ม

บางทีคำว่า "ผู้ฟังเหตุการณ์" กำลังขว้างคุณไป คำนี้แสดงให้เห็นว่า "ผู้ฟัง" กำลังทำอะไรบางอย่างเพื่อฟัง แต่จริงๆแล้วมันไม่ได้ทำอะไรเลย "ผู้ฟัง" เป็นเพียงฟังก์ชั่นหรือวิธีการที่เป็นสมาชิกของเหตุการณ์ เมื่อเหตุการณ์เริ่มทำงานเมธอด listener ("event handler") จะถูกเรียก

ประโยชน์ของรูปแบบเหตุการณ์คือไม่มีค่าใช้จ่ายจนกว่าจะกดปุ่มจริง เหตุการณ์สามารถจัดการได้ด้วยวิธีนี้โดยไม่ได้รับการตรวจสอบเพราะเกิดจากสิ่งที่เราเรียกว่า "ฮาร์ดแวร์ขัดจังหวะ" ซึ่งเป็นการชั่วคราวเรียกรหัสเพื่อเรียกใช้เหตุการณ์

UI และเฟรมเวิร์กเกมบางอย่างใช้สิ่งที่เรียกว่า "การวนรอบข้อความ" ซึ่งจะจัดคิวเหตุการณ์สำหรับการดำเนินการในช่วงเวลาต่อมา (โดยปกติจะสั้น) แต่คุณยังต้องมีการขัดจังหวะฮาร์ดแวร์เพื่อให้เหตุการณ์นั้นเข้าสู่การวนรอบข้อความ


54
มันอาจจะคุ้มค่าที่จะกล่าวถึงเหตุผลที่ไม่มีค่าใช้จ่ายจนกว่าจะกดปุ่มเพราะปุ่มเป็น "พิเศษ" คอมพิวเตอร์มีการขัดจังหวะและสิ่งอำนวยความสะดวกพิเศษอื่น ๆ ที่ระบบปฏิบัติการสามารถใช้งานได้
whatsisname

46
@whatsisname ในขณะที่เป็นกรณีที่ลึกมากภายใต้ประทุนในทางปฏิบัติเครื่องมือเกมอาจไม่ทำงานกับการขัดจังหวะ แต่ในความเป็นจริงยังคงสำรวจแหล่งที่มาของเหตุการณ์ในวง มันเป็นแค่ที่หน่วยเลือกตั้งนี้เป็นศูนย์กลางและเพิ่มประสิทธิภาพเพื่อให้การเพิ่มฟังเหตุการณ์มากขึ้นไม่ได้เพิ่มเพิ่มเติมเลือกตั้งและความซับซ้อน
gntskn

7
@PieterGeerkens ฉันเดาว่า gntskn หมายความว่าเป็นส่วนหนึ่งของลูปเอ็นจิ้นเกมมีขั้นตอนที่จะตรวจสอบกิจกรรมที่ยอดเยี่ยมใด ๆ กิจกรรมจะถูกประมวลผลระหว่างแต่ละวงพร้อมกับกิจกรรมครั้งเดียวต่อวงอื่น ๆ ทั้งหมด จะไม่มีลูปแยกต่างหากสำหรับตรวจสอบเหตุการณ์
Joshua Taylor

2
@Voo: เหตุผลทั้งหมดที่จะไม่เข้าไปดูรายละเอียดในระดับนี้ในโพสต์นี้
Robert Harvey

2
@Voo: ฉันกำลังพูดถึงปุ่มเช่นเดียวกับปุ่มทางกายภาพบนแป้นพิมพ์และปุ่มเมาส์
whatsisname

52

ฟังเหตุการณ์คล้ายกับการสมัครรับจดหมายข่าวทางอีเมล (คุณลงทะเบียนตัวเองเพื่อรับการปรับปรุงซึ่งมีการส่งในภายหลังโดยผู้ส่ง) แทนที่จะรีเฟรชหน้าเว็บอย่างไม่สิ้นสุด (ซึ่งคุณเป็นผู้เริ่มการถ่ายโอนข้อมูล)

ระบบเหตุการณ์ถูกนำมาใช้โดยใช้วัตถุเหตุการณ์ซึ่งจัดการรายชื่อสมาชิก วัตถุที่สนใจ (เรียกว่าสมาชิก , ฟัง , ผู้ได้รับมอบหมายฯลฯ ) สามารถสมัครตัวเองเพื่อรับทราบเหตุการณ์โดยเรียกวิธีการที่เป็นสมาชิกของตัวเองที่จะมีเหตุการณ์ซึ่งเป็นสาเหตุของเหตุการณ์ที่จะเพิ่มเข้าไปในรายการ เมื่อใดก็ตามที่เหตุการณ์จะยิง (คำศัพท์ยังสามารถรวม: เรียก , เรียก , เรียก , ทำงานฯลฯ ) ที่เรียกว่าวิธีการที่เหมาะสมในแต่ละของสมาชิกที่จะแจ้งให้ทราบถึงเหตุการณ์ที่ผ่านไปสิ่งที่ข้อมูลบริบทที่พวกเขาต้องการที่จะเข้าใจ เกิดอะไรขึ้น.


38

คำตอบสั้น ๆ ที่ไม่น่าพึงพอใจคือแอปพลิเคชั่นได้รับสัญญาณ (เหตุการณ์) และรูทีนนั้นเรียกเฉพาะที่จุดนั้น

คำอธิบายที่ยาวขึ้นเกี่ยวข้องกับอีกเล็กน้อย

เหตุการณ์ไคลเอนต์มาจากไหน

แต่ละแอปพลิเคชั่นที่ทันสมัยมี "วงเหตุการณ์" แบบกึ่งซ่อนเร้นซึ่งจะส่งเหตุการณ์ไปยังองค์ประกอบที่ถูกต้องที่ควรรับ ตัวอย่างเช่นเหตุการณ์ "คลิก" จะถูกส่งไปยังปุ่มที่พื้นผิวสามารถมองเห็นได้ที่พิกัดเมาส์ปัจจุบัน นี่คือระดับที่ง่ายที่สุด ในความเป็นจริงแล้วระบบปฏิบัติการจะทำการส่งข้อมูลจำนวนมากเนื่องจากเหตุการณ์บางอย่างและส่วนประกอบบางอย่างจะได้รับข้อความโดยตรง

กิจกรรมแอปพลิเคชันมาจากที่ใด

ระบบปฏิบัติการจัดส่งเหตุการณ์ที่เกิดขึ้น พวกเขาทำอย่างกระตือรือร้นโดยได้รับการแจ้งเตือนจากคนขับเอง

ไดรเวอร์สร้างกิจกรรมได้อย่างไร

ฉันไม่ได้เป็นผู้เชี่ยวชาญ แต่มีบางคนใช้ CPU ขัดจังหวะ: ฮาร์ดแวร์ที่พวกเขาควบคุมยกขาบน CPU เมื่อมีข้อมูลใหม่ CPU จะดับไดรเวอร์ซึ่งจัดการข้อมูลที่เข้ามาซึ่งในที่สุดจะสร้างเหตุการณ์ (คิว) ที่จะส่งและจากนั้นส่งคืนการควบคุมกลับไปยังระบบปฏิบัติการ

ดังที่คุณเห็นแอปพลิเคชันของคุณไม่ได้ทำงานอยู่ตลอดเวลา มันเป็นกระบวนการหลายอย่างที่ระบบปฏิบัติการ (sorta) ใช้เมื่อเหตุการณ์เกิดขึ้น แต่ไม่ทำอะไรเลยเวลาที่เหลือ


มีข้อยกเว้นที่น่าสังเกตเช่นเกมหนึ่งครั้งซึ่งอาจทำสิ่งต่าง ๆ ได้


10
คำตอบนี้อธิบายว่าทำไมไม่มีการสำรวจที่เกี่ยวข้องกับเหตุการณ์การคลิกเมาส์ในเบราว์เซอร์ ฮาร์ดแวร์สร้างอินเตอร์รัปต์ => ไดรเวอร์แก้ไขให้เป็นเหตุการณ์ OS => เบราว์เซอร์แก้ไขให้เป็นเหตุการณ์ DOM => เอ็นจิ้น JS รันผู้ฟังสำหรับเหตุการณ์นั้น
Tibos

@Tibos AFAICT ก็ยังนำไปใช้กับเหตุการณ์ที่เกิดขึ้นแป้นพิมพ์เหตุการณ์จับเวลาเหตุการณ์สี ฯลฯ
Sklivvz

19

คำศัพท์

  • เหตุการณ์ : ประเภทของสิ่งที่สามารถเกิดขึ้นได้

  • การยิงของเหตุการณ์ : เหตุการณ์เฉพาะ; เหตุการณ์ที่เกิดขึ้น

  • ฟังเหตุการณ์ : บางสิ่งบางอย่างที่มองออกไปจากเหตุการณ์ไล่ออก

  • ตัวจัดการเหตุการณ์ : สิ่งที่เกิดขึ้นเมื่อผู้ฟังเหตุการณ์ตรวจพบการยิงของเหตุการณ์

  • สมาชิกของเหตุการณ์ : การตอบสนองที่ตัวจัดการเหตุการณ์ที่ควรจะเรียก

คำจำกัดความเหล่านี้ไม่ได้ขึ้นอยู่กับการนำไปใช้งานดังนั้นจึงสามารถนำไปใช้งานได้หลายวิธี

บางคำศัพท์เหล่านี้มักเข้าใจผิดว่าเป็นคำพ้องความหมายเนื่องจากผู้ใช้ไม่จำเป็นต้องแยกแยะระหว่างคำเหล่านั้น

สถานการณ์ทั่วไป

  1. เหตุการณ์การเขียนโปรแกรมลอจิก

    • เหตุการณ์คือเมื่อวิธีการบางอย่างได้รับการเรียก

    • การยิงเหตุการณ์เป็นการเรียกวิธีการนั้นโดยเฉพาะ

    • ฟังเหตุการณ์เป็นเบ็ดในวิธีกรณีที่เรียกว่าในแต่ละเหตุการณ์ยิงที่เรียกตัวจัดการเหตุการณ์

    • จัดการเหตุการณ์เรียกคอลเลกชันของสมาชิกเหตุการณ์

    • สมาชิกเหตุการณ์ (s)ดำเนินการสิ่งที่กระทำ (s) ระบบหมายความว่าจะเกิดขึ้นในการตอบสนองต่อการเกิดเหตุการณ์

  2. เหตุการณ์ภายนอก

    • เหตุการณ์เป็นสิ่งที่เกิดขึ้นภายนอกที่สามารถอนุมานจาก observables

    • ยิงเหตุการณ์คือเมื่อที่เกิดขึ้นภายนอกได้รับการยอมรับว่ามีการเกิดขึ้น

    • ฟังเหตุการณ์อย่างใดตรวจพบไล่ออกเหตุการณ์โดยมักจะเลือกตั้งสังเกต (s), แล้วมันเรียกตัวจัดการเหตุการณ์เมื่อตรวจหาการยิงเหตุการณ์

    • จัดการเหตุการณ์เรียกคอลเลกชันของสมาชิกเหตุการณ์

    • สมาชิกเหตุการณ์ (s)ดำเนินการสิ่งที่กระทำ (s) ระบบหมายความว่าจะเกิดขึ้นในการตอบสนองต่อการเกิดเหตุการณ์

การสำรวจกับการสอดตะขอเข้าไปในกลไกการยิงของเหตุการณ์

จุดที่คนอื่นทำคือการเลือกตั้งบ่อยครั้งไม่จำเป็น นี่เป็นเพราะผู้ฟังเหตุการณ์สามารถนำไปใช้งานได้โดยให้เหตุการณ์ไล่ออกโดยอัตโนมัติเรียกตัวจัดการเหตุการณ์ซึ่งเป็นวิธีที่มีประสิทธิภาพที่สุดในการนำสิ่งต่าง ๆ มาใช้เมื่อเหตุการณ์เกิดขึ้นในระดับระบบ

โดยการเปรียบเทียบคุณไม่จำเป็นต้องตรวจสอบกล่องจดหมายของคุณสำหรับอีเมลทุกวันหากพนักงานไปรษณีย์เคาะประตูและส่งอีเมลถึงคุณโดยตรง

อย่างไรก็ตามฟังเหตุการณ์สามารถทำงานได้โดยการสำรวจ การสำรวจความคิดเห็นไม่จำเป็นต้องตรวจสอบค่าเฉพาะหรือสิ่งอื่นที่สังเกตได้ มันซับซ้อนกว่านี้ได้ แต่โดยรวมแล้วจุดประสงค์ของการสำรวจคือการอนุมานเมื่อมีเหตุการณ์บางอย่างเกิดขึ้นซึ่งสามารถตอบสนองได้

โดยการเปรียบเทียบคุณต้องตรวจสอบกล่องจดหมายของคุณทุกวันเมื่อพนักงานไปรษณีย์เพิ่งส่งจดหมายลงไป คุณไม่จำเป็นต้องทำงานหน่วยเลือกตั้งนี้หากคุณสามารถสั่งให้พนักงานไปรษณีย์ทำการเคาะประตูของคุณ แต่นั่นก็ไม่ได้เป็นไปได้

ตรรกะของเหตุการณ์การโยง

ในภาษาการเขียนโปรแกรมหลายภาษาคุณสามารถเขียนเหตุการณ์ที่เพิ่งเรียกเมื่อมีการกดแป้นบนแป้นพิมพ์หรือในเวลาที่กำหนด แม้ว่าสิ่งเหล่านี้จะเป็นเหตุการณ์ภายนอกคุณไม่จำเป็นต้องสำรวจความคิดเห็น ทำไม?

มันเป็นเพราะระบบปฏิบัติการกำลังทำการสำรวจเพื่อคุณ ตัวอย่างเช่น Windows จะตรวจสอบสิ่งต่าง ๆ เช่นการเปลี่ยนแปลงสถานะของแป้นพิมพ์และหากตรวจพบสิ่งใดสิ่งหนึ่งมันจะเรียกสมาชิกของเหตุการณ์ ดังนั้นเมื่อคุณสมัครรับข้อมูลกิจกรรมการกดแป้นพิมพ์คุณจะสมัครรับข้อมูลกิจกรรมที่เป็นสมาชิกของกิจกรรมที่โพล

โดยการเปรียบเทียบให้บอกว่าคุณอาศัยอยู่ในอพาร์ทเมนต์คอมเพล็กซ์และพนักงานไปรษณีย์ส่งจดหมายไปยังพื้นที่รับจดหมายของชุมชน จากนั้นผู้ปฏิบัติงานที่ใช้ระบบปฏิบัติการสามารถตรวจสอบจดหมายนั้นสำหรับทุกคนโดยส่งจดหมายไปยังอพาร์ตเมนต์ของผู้ที่ได้รับบางสิ่งบางอย่าง วิธีนี้ช่วยให้ทุกคนมีปัญหาในการสำรวจพื้นที่รับจดหมาย


สัญชาตญาณของฉันจะถือว่าผู้ฟังเหตุการณ์ตรวจสอบอย่างต่อเนื่องว่าเหตุการณ์ถูกยิงหรือไม่ความหมายในสถานการณ์ของฉันมันจะไม่แตกต่างจากการตรวจสอบทุกเฟรมหากเหตุการณ์นั้นถูกไล่ออก

จากการอภิปรายในชั้นเรียนดูเหมือนว่าผู้ฟังเหตุการณ์จะทำงานในลักษณะที่แตกต่างออกไป

ฟังเหตุการณ์ทำงานอย่างไร

ในขณะที่คุณสงสัยว่าเหตุการณ์สามารถทำงานผ่านการสำรวจ และหากเหตุการณ์ใดที่เกี่ยวข้องกับเหตุการณ์ภายนอกเช่นการกดแป้นคีย์บอร์ดการเลือกตั้งจะต้องเกิดขึ้นในบางจุด

เป็นความจริงที่ว่าเหตุการณ์ไม่จำเป็นต้องเกี่ยวข้องกับการลงคะแนนเลือกตั้ง ตัวอย่างเช่นหากเหตุการณ์เกิดขึ้นเมื่อกดปุ่มผู้ฟังเหตุการณ์ของปุ่มนั้นเป็นวิธีการที่กรอบงาน GUI อาจเรียกใช้เมื่อพิจารณาว่าการคลิกเมาส์กระทบปุ่ม ในกรณีนี้การสำรวจยังคงเกิดขึ้นสำหรับการตรวจจับการคลิกเมาส์ แต่ตัวฟังเมาส์เป็นองค์ประกอบแบบพาสซีฟมากกว่าที่เชื่อมต่อกับกลไกการลงคะแนนแบบดั้งเดิมผ่านการโยงเหตุการณ์

อัปเดต: สำหรับการสำรวจฮาร์ดแวร์ระดับต่ำ

ปรากฎว่าอุปกรณ์ USB และโปรโตคอลการสื่อสารที่ทันสมัยอื่น ๆ มีชุดของโปรโตคอลสำหรับการโต้ตอบที่น่าดึงดูดใจทำให้อุปกรณ์ I / O รวมถึงแป้นพิมพ์และเมาส์มีส่วนร่วมในทอพอโลยีแบบเฉพาะกิจ

สิ่งที่น่าสนใจคือ "การขัดจังหวะ " เป็นสิ่งที่ค่อนข้างจำเป็นและเป็นแบบซิงโครนัสดังนั้นพวกเขาจึงไม่จัดการทอพอโลยีเครือข่ายแบบเฉพาะกิจ เพื่อแก้ไขปัญหานี้ " ขัดจังหวะ " ได้รับการทั่วไปเข้าไม่ตรงกันแพ็คเก็ตมีความสำคัญสูงที่เรียกว่า" การทำธุรกรรมการขัดจังหวะ " (ในบริบทของ USB) หรือ" การขัดจังหวะข้อความส่งสัญญาณ " (ในบริบทของของ PCI) โปรโตคอลนี้ได้อธิบายไว้ในข้อมูลจำเพาะของ USB:

ป้อนคำอธิบายรูปภาพที่นี่

- " รูปที่ 8-31. เครื่องสถานะโฮสต์ธุรกรรม / การควบคุม / ขัดจังหวะ OUT " ใน"ข้อมูลจำเพาะ Universal Serial Bus, Revision 2.0" , printed-page-222; PDF-page-250 (2000-04-27)

สรุปสาระสำคัญดูเหมือนว่าอุปกรณ์ I / O และส่วนประกอบการสื่อสาร (เช่นฮับ USB) โดยทั่วไปจะทำหน้าที่เหมือนอุปกรณ์เครือข่าย ดังนั้นพวกเขาจึงส่งข้อความซึ่งจำเป็นต้องมีการสำรวจพอร์ตและเช่นนั้น สิ่งนี้ช่วยลดความจำเป็นในการใช้สายฮาร์ดแวร์เฉพาะ

ระบบปฏิบัติการเช่น Windows ดูเหมือนจะจัดการกับกระบวนการเลือกตั้งของตัวเองเช่นที่อธิบายไว้ในเอกสาร MSDN สำหรับUSB_ENDPOINT_DESCRIPTOR'sซึ่งอธิบายถึงวิธีการควบคุมความถี่ของ Windows โพลล์ตัวควบคุมโฮสต์ USB สำหรับข้อความขัดจังหวะ / isochronous:

bIntervalค่ามีช่วงการเลือกตั้งสำหรับการขัดจังหวะและ isochronous ปลายทาง สำหรับจุดปลายประเภทอื่นค่านี้ควรถูกละเว้น ค่านี้สะท้อนถึงการกำหนดค่าอุปกรณ์ในเฟิร์มแวร์ ไดรเวอร์ไม่สามารถเปลี่ยนได้

ช่วงเวลาการทำโพลพร้อมกับความเร็วของอุปกรณ์และประเภทของโฮสต์คอนโทรลเลอร์กำหนดความถี่ที่ไดรเวอร์ควรเริ่มต้นการอินเตอร์รัปต์หรือการถ่ายโอนแบบ isochronous ค่าในbIntervalไม่ได้แสดงระยะเวลาที่แน่นอน เป็นค่าสัมพัทธ์และความถี่ในการทำโพลที่แท้จริงจะขึ้นอยู่กับว่าอุปกรณ์และตัวควบคุมโฮสต์ USB ทำงานที่ความเร็วต่ำเต็มหรือสูง

- "USB_ENDPOINT_DESCRIPTOR โครงสร้าง" , Hardware Dev Center, Microsoft

ใหม่กว่าโปรโตคอลการเชื่อมต่อจอภาพเช่นDisplayPortดูเหมือนจะทำเช่นเดียวกัน:

การขนส่งหลายสตรีม (MST)

  • เพิ่ม MST (Multi-Stream Transport) ใน DisplayPort Ver.1.2

    • เฉพาะ SST (Single-Stream Transport) มีให้ใน Ver.1.1a
  • MST ส่งกระแสข้อมูล A / V หลายกระแสผ่านตัวเชื่อมต่อเดียว

    • มากถึง 63 สตรีม; ไม่ใช่“ สตรีมต่อเลน”

      • ไม่มีการสันนิษฐานว่าเป็นเรื่องบังเอิญในหมู่สตรีมที่ถูกขนส่ง สตรีมหนึ่งรายการอาจอยู่ในช่วง blanking ขณะที่สตรีมอื่นไม่ใช่
    • การขนส่งที่มุ่งเน้นการเชื่อมต่อ

      • พา ธ จากแหล่งที่มาของกระแสข้อมูลไปยังที่เก็บกระแสข้อมูลเป้าหมายที่สร้างขึ้นผ่านธุรกรรมข้อความผ่าน AUX CH AUXs ก่อนที่จะเริ่มการส่งกระแสข้อมูล

      • การเพิ่ม / ลบสตรีมโดยไม่มีผลกระทบกับสตรีมที่เหลือ

ป้อนคำอธิบายรูปภาพที่นี่

-Slide # 14 จาก"ภาพรวม DisplayPortTM Ver.1.2" (2010-12-06)

สิ่งที่เป็นนามธรรมนี้อนุญาตให้ใช้คุณสมบัติที่เป็นระเบียบบางอย่างเช่นการรันจอภาพ 3 จอจากการเชื่อมต่อเดียว:

DisplayPort Multi-Stream Transport ยังอนุญาตให้เชื่อมต่ออุปกรณ์สามตัวหรือมากกว่าเข้าด้วยกัน แต่ในทางกลับกันการกำหนดค่าแบบ "ผู้บริโภค" ที่น้อยลง: ขับจอหลายจอพร้อมกันจากพอร์ตเอาต์พุตเดียว

- "DisplayPort" , Wikipedia

ตามหลักการแล้วประเด็นที่ต้องคำนึงถึงก็คือกลไกการสำรวจความคิดเห็นอนุญาตให้มีการสื่อสารแบบอนุกรมทั่วไปซึ่งยอดเยี่ยมมากเมื่อคุณต้องการฟังก์ชั่นทั่วไป ดังนั้นฮาร์ดแวร์และระบบปฏิบัติการจึงทำโพลจำนวนมากสำหรับระบบโลจิคัล จากนั้นผู้บริโภคที่สมัครรับกิจกรรมสามารถเพลิดเพลินไปกับรายละเอียดที่จัดการให้พวกเขาโดยระบบระดับล่างโดยไม่ต้องเขียนโปรโตคอล / การส่งข้อความผ่านของตนเอง

ในที่สุดเหตุการณ์เช่นกดปุ่มดูเหมือนจะผ่านชุดที่น่าสนใจของเหตุการณ์ก่อนที่จะไปถึงกลไกการยิงเหตุการณ์ระดับความจำเป็นของซอฟต์แวร์


ตามวรรคสุดท้ายของคุณไม่มีการทำโพลในระดับต่ำระบบปฏิบัติการตอบสนองต่อการขัดจังหวะของฮาร์ดแวร์ที่เกิดจากอุปกรณ์ต่อพ่วง คอมพิวเตอร์มักจะมีอุปกรณ์ที่เชื่อมต่ออยู่มากมาย (เมาส์แป้นพิมพ์ดิสก์ไดรฟ์การ์ดเครือข่าย) และการสำรวจความคิดเห็นทั้งหมดจะไม่มีประสิทธิภาพมาก
Barmar

อย่างไรก็ตามการเปรียบเทียบของคุณกับการส่งจดหมายนั้นเป็นวิธีที่ฉันจะอธิบายกิจกรรมระดับที่สูงขึ้น
Barmar

1
@Barmar Ya รู้ว่าเมื่ออุปกรณ์ย้ายไปยังการเชื่อมต่อ USB มีการพูดคุยกันมากมายเกี่ยวกับวิธีการสร้างอินเตอร์รัปต์โดยตรง (เช่นแป้นพิมพ์ PS / 2) ไปสู่การลงคะแนนเลือกตั้ง (เช่นแป้นพิมพ์ USB) และบางแหล่งข่าวอ้างว่า ที่หน่วยเลือกตั้งทำโดยซีพียู แต่แหล่งข้อมูลอื่นอ้างว่ามันทำบนคอนโทรลเลอร์พิเศษที่แปลงการสำรวจให้เป็นอินเตอร์รัปต์สำหรับ CPU
Nat

@Barmar คุณจะรู้หรือไม่ว่าอะไรถูกต้อง? ฉันอาจเห็นแหล่งที่มามากกว่าอ้างว่า CPU ทำโพลมากกว่าที่อื่น แต่ตัวควบคุมพิเศษสำหรับมันดูเหมือนจะสมเหตุสมผลมากขึ้น ฉันหมายถึงฉันคิดว่า Arduino และอุปกรณ์ฝังตัวอื่น ๆ มักจะต้องการให้ CPU ทำการสำรวจ แต่ฉันไม่รู้เกี่ยวกับอุปกรณ์ชนิด x86
Nat

1
ถ้าใครสามารถยืนยันได้ดังนั้นฉันสามารถปรับปรุงคำตอบนี้ผมคิดว่าผมที่ทันสมัย / O อุปกรณ์เช่นผู้ที่เชื่อมต่อด้วย USB, เขียนโดยตรงในหน่วยความจำผ่านการควบคุมของ CPU (ซึ่งเป็นทั้งทำไมพวกเขากำลังอย่างรวดเร็ว / มีประสิทธิภาพและการรักษาความปลอดภัย อันตรายในบางครั้ง ) จากนั้นต้องใช้ระบบปฏิบัติการที่ทันสมัยในการสำรวจหน่วยความจำเพื่อตรวจสอบข้อความใหม่
Nat

8

ดึงกับดัน

มีสองกลยุทธ์หลักในการตรวจสอบว่ามีเหตุการณ์ที่เกิดขึ้นหรือถึงสถานะที่เฉพาะเจาะจง ตัวอย่างเช่นลองจินตนาการว่ากำลังรอการส่งมอบที่สำคัญ:

  • ดึง : ทุก ๆ 10 นาทีลงไปที่กล่องจดหมายของคุณและตรวจสอบว่าได้ส่งมอบหรือไม่
  • Push : บอกคนส่งของให้โทรหาคุณเมื่อพวกเขาส่งมอบ

ดึงวิธี (ที่เรียกว่าหน่วยเลือกตั้ง) จะง่าย: คุณสามารถใช้มันได้โดยไม่ต้องมีคุณสมบัติพิเศษใด ๆ ในทางกลับกันก็มักจะมีประสิทธิภาพน้อยลงเนื่องจากคุณเสี่ยงต่อการตรวจสอบเพิ่มเติมโดยไม่แสดงอะไร

ในทางกลับกันวิธีการพุชมักจะมีประสิทธิภาพมากกว่า: โค้ดของคุณจะทำงานเมื่อมีสิ่งที่ต้องทำ บนมืออื่น ๆ ก็ต้องว่ากลไกที่มีอยู่สำหรับการลงทะเบียนเป็นผู้ฟัง / ผู้สังเกตการณ์ / โทรกลับ1

1 โดยทั่วไปแล้วคนส่งจดหมายของฉันขาดกลไกดังกล่าวโชคไม่ดี


1

เกี่ยวกับความเป็นเอกภาพโดยเฉพาะ - ไม่มีวิธีอื่นในการตรวจสอบอินพุตของผู้เล่นอื่นนอกจากการสำรวจทุก ๆ เฟรม ในการสร้างผู้ฟังเหตุการณ์คุณจะต้องมีวัตถุเช่น "ระบบเหตุการณ์" หรือ "ผู้จัดการเหตุการณ์" เพื่อทำการสำรวจดังนั้นมันจะผลักปัญหาไปยังคลาสอื่นเท่านั้น

ได้รับเมื่อคุณมีผู้จัดการกิจกรรมคุณมีเพียงชั้นเดียวที่จะทำการสำรวจความคิดเห็นทุก ๆ เฟรม แต่นี่ไม่ได้ให้ประโยชน์ด้านประสิทธิภาพที่ชัดเจนเนื่องจากตอนนี้คลาสนี้ต้องทำซ้ำมากกว่าผู้ฟังและเรียกพวกเขาซึ่งขึ้นอยู่กับเกมของคุณ การออกแบบ (ในจำนวนผู้ฟังที่มีและความถี่ที่ผู้เล่นใช้อินพุต) จริงอาจมีราคาแพงกว่า

นอกเหนือจากทั้งหมดนี้โปรดจำไว้ว่ากฎทองคำ - การปรับให้เหมาะสมก่อนกำหนดเป็นรากของความชั่วร้ายทั้งหมดซึ่งเป็นจริงโดยเฉพาะอย่างยิ่งในวิดีโอเกมซึ่งบ่อยครั้งที่กระบวนการแสดงภาพแต่ละเฟรมมีค่าใช้จ่ายสูง


ฉันจะไม่เห็นการวนรอบศูนย์กลางเหตุการณ์เป็นการเพิ่มประสิทธิภาพ แต่เนื่องจากการเขียนโค้ดที่อ่านง่ายและเข้าใจได้มากกว่าการโพลแบบกระจายทั่วฐานรหัส นอกจากนี้ยังช่วยให้เหตุการณ์“ สังเคราะห์” และเหตุการณ์ที่ไม่ได้มาจากการสำรวจเอ็นจิ้นเกม
BlackJack

@ BlackJack ฉันเห็นด้วยและฉันมักจะเขียนมันด้วยวิธีนี้ แต่ OP ถามเกี่ยวกับประสิทธิภาพ Btw, Unity มีการตัดสินใจออกแบบรหัสที่น่าสงสัยมากมายเช่นนี้เช่นมีฟังก์ชั่นคงที่เกือบทุกที่
Dunno

1

หากคุณไม่ได้รับการสนับสนุนใน OS / Framework ของคุณที่จัดการกับเหตุการณ์เช่นการกดปุ่มหรือโอเวอร์โฟลว์จับเวลาหรือการมาถึงข้อความ - คุณจะต้องนำรูปแบบผู้ฟังเหตุการณ์นี้มาใช้โดยการโพลต่อไป

แต่อย่าหันหน้าหนีจากรูปแบบการออกแบบนี้เพียงเพราะคุณไม่ได้รับประโยชน์ด้านประสิทธิภาพที่นั่นทันที นี่คือเหตุผลที่คุณควรใช้โดยไม่คำนึงว่าคุณมีการสนับสนุนด้านล่างสำหรับการจัดการเหตุการณ์หรือไม่

  1. รหัสดูสะอาดตาและโดดเดี่ยวมากขึ้น (หากใช้อย่างถูกต้องแน่นอน)
  2. รหัสที่ยึดตามตัวจัดการเหตุการณ์จะเปลี่ยนได้ดีกว่าเดิม (เนื่องจากปกติคุณจะแก้ไขตัวจัดการเหตุการณ์บางส่วนเท่านั้น)
  3. หากคุณเกิดขึ้นที่จะย้ายไปที่แพลตฟอร์มด้วยการสนับสนุนกิจกรรม underlaying - คุณสามารถใช้ตัวจัดการเหตุการณ์ที่มีอยู่แล้วและกำจัดรหัสการลงคะแนน

บทสรุป - คุณโชคดีที่ได้มีส่วนร่วมในการอภิปรายและเรียนรู้วิธีการหนึ่งในการเลือกตั้ง มองหาโอกาสที่จะนำแนวคิดนี้ไปใช้ในทางปฏิบัติและคุณจะประทับใจกับความสวยงามของรหัส


1

เหตุการณ์ส่วนใหญ่จะถูกสร้างขึ้นด้านบนแบบดั้งเดิมการทำมัลติโพลมัลติโพลให้โดยระบบปฏิบัติการ บน Linux ดั้งเดิมนั้นมักจะเป็นการเรียกระบบpoll(2) (แต่อาจเป็นสายเก่าselect) ในแอปพลิเคชัน GUI เซิร์ฟเวอร์แสดงผล (เช่นXorgหรือWayland ) กำลังสื่อสาร (ผ่านซ็อกเก็ต (7)หรือไพพ์ (7) ) กับแอปพลิเคชันของคุณ อ่านยังเกี่ยวกับวินโดว์โปรโตคอลระบบและสถาปัตยกรรม

วิธีการสำรวจแบบดั้งเดิมนั้นมีประสิทธิภาพ เคอร์เนลในทางปฏิบัติจะตื่นขึ้นมากระบวนการของคุณเมื่อมีการป้อนข้อมูลบางอย่าง (และการขัดจังหวะบางอย่างได้รับการจัดการ)

ห้องสมุดชุดเครื่องมือวิดเจ็ตของคุณสื่อสารกับเซิร์ฟเวอร์การแสดงผลรอข้อความและส่งข้อความเหล่านี้ไปยังวิดเจ็ตของคุณ ไลบรารีชุดเครื่องมือเช่นQtหรือGTKนั้นค่อนข้างซับซ้อน (ซอร์สโค้ดหลายล้านบรรทัด) แป้นพิมพ์และเมาส์ของคุณได้รับการจัดการโดยกระบวนการเซิร์ฟเวอร์การแสดงผลเท่านั้น (ซึ่งแปลอินพุตดังกล่าวเป็นข้อความเหตุการณ์ที่ส่งไปยังแอปพลิเคชันไคลเอนต์)

(ฉันทำให้เข้าใจง่ายขึ้น แต่ที่จริงแล้วสิ่งต่าง ๆ มีความซับซ้อนมากขึ้น)


1

ในระบบที่ใช้โพลล้วนระบบย่อยที่อาจต้องการทราบเมื่อมีการกระทำบางอย่างเกิดขึ้นจะต้องเรียกใช้โค้ดในเวลาที่การกระทำนั้นอาจเกิดขึ้น หากมีระบบย่อยจำนวนมากที่แต่ละคนต้องตอบสนองภายใน 10ms ของเหตุการณ์ที่ไม่จำเป็นต้องเกิดขึ้นพวกเขาทุกคนต้องตรวจสอบอย่างน้อย 100 ครั้ง / วินาทีไม่ว่าจะเกิดเหตุการณ์ขึ้นหรือไม่ หากระบบย่อยเหล่านั้นอยู่ในกระบวนการที่แตกต่างกัน (หรือแย่กว่ากระบวนการ) ซึ่งจะต้องมีการสลับในทุก ๆ กระทู้หรือกระบวนการ 100x / วินาที

หากมีหลายสิ่งที่แอปพลิเคชันจะดูคล้ายกันมันอาจจะมีประสิทธิภาพมากกว่าถ้ามีระบบย่อยการติดตามแบบรวมศูนย์ - อาจเป็นระบบขับเคลื่อนแบบตาราง - ซึ่งสามารถดูได้หลายสิ่งและสังเกตว่ามีการเปลี่ยนแปลงใด ๆ หากมี 32 สวิตช์ตัวอย่างเช่นแพลตฟอร์มอาจมีฟังก์ชั่นอ่าน 32 สวิตช์ทั้งหมดพร้อมกันในหนึ่งคำทำให้รหัสตรวจสอบสามารถตรวจสอบได้ว่าสวิตช์ใดมีการเปลี่ยนแปลงระหว่างการสำรวจและ - ถ้าไม่ - ไม่ กังวลว่ารหัสใดที่พวกเขาอาจสนใจ

หากมีระบบย่อยจำนวนมากที่ต้องการการแจ้งเตือนเมื่อมีการเปลี่ยนแปลงบางอย่างการมีระบบย่อยการตรวจสอบเฉพาะแจ้งเตือนระบบย่อยอื่นเมื่อเหตุการณ์เกิดขึ้นที่พวกเขาสนใจอาจมีประสิทธิภาพมากกว่าการให้แต่ละระบบย่อยสำรวจเหตุการณ์ของตนเอง การตั้งค่าระบบย่อยการตรวจสอบเฉพาะในกรณีที่ไม่มีใครสนใจเหตุการณ์ใด ๆ แต่จะแสดงถึงการสูญเสียทรัพยากรที่บริสุทธิ์ หากมีระบบย่อยเพียงไม่กี่แห่งที่สนใจในเหตุการณ์ค่าใช้จ่ายในการเฝ้าดูกิจกรรมที่พวกเขาสนใจอาจน้อยกว่าค่าใช้จ่ายในการตั้งค่าระบบย่อยการตรวจสอบเฉพาะสำหรับจุดประสงค์ทั่วไป แต่จุดคุ้มทุน จุดจะแตกต่างกันอย่างมีนัยสำคัญระหว่างแพลตฟอร์มที่แตกต่างกัน


0

ฟังเหตุการณ์เป็นหูรอข้อความ เมื่อมีเหตุการณ์เกิดขึ้นรูทีนย่อยที่เลือกเป็น listener event จะทำงานโดยใช้อาร์กิวเมนต์ของเหตุการณ์

มีข้อมูลสำคัญสองอย่างเสมอ: ช่วงเวลาที่เหตุการณ์เกิดขึ้นและวัตถุที่เกิดเหตุการณ์นี้ อาร์กิวเมนต์อื่นเป็นข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่เกิดขึ้น

ฟังเหตุการณ์ระบุปฏิกิริยาที่เกิดขึ้น


0

ฟังเหตุการณ์ตามรูปแบบการเผยแพร่ / สมัครสมาชิก (ในฐานะสมาชิก)

ในรูปแบบที่ง่ายที่สุดอ็อบเจกต์การเผยแพร่จะเก็บรายการคำแนะนำของสมาชิกที่จะดำเนินการเมื่อมีบางสิ่งที่จำเป็นต้องเผยแพร่

มันจะมีวิธีการบางอย่างsubscribe(x)โดยที่ x ขึ้นอยู่กับวิธีการออกแบบตัวจัดการเหตุการณ์เพื่อจัดการกับเหตุการณ์ เมื่อเรียกใช้การสมัครสมาชิก (x) x จะถูกเพิ่มในรายการผู้เผยแพร่ของคำแนะนำ / การอ้างอิงของสมาชิก

ผู้เผยแพร่อาจมีเหตุผลทั้งหมดหรือบางส่วนในการจัดการเหตุการณ์ มันอาจต้องมีการอ้างอิงไปยังสมาชิกเพื่อแจ้ง / แปลงพวกเขาด้วยตรรกะที่ระบุเมื่อเหตุการณ์เกิดขึ้น มันอาจไม่มีเหตุผลและต้องการวัตถุสมาชิก (วิธีการ / ฟังเหตุการณ์) ที่สามารถจัดการกับเหตุการณ์ มีแนวโน้มมากที่สุดที่จะมีส่วนผสมของทั้งสองอย่าง

เมื่อมีเหตุการณ์เกิดขึ้นผู้เผยแพร่จะวนซ้ำและดำเนินการตรรกะสำหรับแต่ละรายการในรายการคำแนะนำ / การอ้างอิงของสมาชิก

ไม่ว่าตัวจัดการเหตุการณ์จะดูซับซ้อนเพียงใดแกนหลักของมันจะเป็นไปตามรูปแบบที่เรียบง่ายนี้

ตัวอย่าง

สำหรับตัวอย่างฟังเหตุการณ์คุณให้เมธอด / ฟังก์ชัน / คำสั่ง / เหตุการณ์ไปยังเมธอดสมัครสมาชิก () ของตัวจัดการเหตุการณ์ ตัวจัดการเหตุการณ์เพิ่มวิธีการในรายการของการเรียกกลับสมาชิก เมื่อมีเหตุการณ์เกิดขึ้นตัวจัดการเหตุการณ์จะวนซ้ำในรายการของมันและเรียกใช้การเรียกกลับแต่ละครั้ง

สำหรับตัวอย่างโลกแห่งความจริงเมื่อคุณสมัครรับจดหมายข่าวใน Exchange Exchange การอ้างอิงไปยังโปรไฟล์ของคุณจะถูกเพิ่มลงในตารางฐานข้อมูลสมาชิก เมื่อถึงเวลาที่จะเผยแพร่จดหมายข่าวการอ้างอิงจะถูกใช้เพื่อเติมแม่แบบของจดหมายข่าวและมันจะถูกส่งไปยังอีเมลของคุณ ในกรณีนี้ x เป็นเพียงการอ้างอิงถึงคุณและผู้จัดพิมพ์มีชุดคำแนะนำภายในที่ใช้สำหรับสมาชิกทั้งหมด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.