เครื่องรัฐเทียบกับหัวข้อ


24

Alan Cox เคยกล่าวไว้ว่า "คอมพิวเตอร์เป็นเครื่องสถานะหัวข้อสำหรับผู้ที่ไม่สามารถตั้งโปรแกรมเครื่องสถานะ"
เนื่องจากการถามอลันโดยตรงไม่ใช่ตัวเลือกสำหรับฉันที่ต่ำต้อยฉันจึงอยากถามที่นี่: วิธีใดที่ทำให้การทำงานแบบมัลติเธรดในภาษาระดับสูงเช่น Java โดยใช้เพียงหนึ่งเธรดและเครื่องสถานะ ตัวอย่างเช่นจะเกิดอะไรขึ้นถ้ามี 2 กิจกรรมที่ต้องดำเนินการ (ทำการคำนวณและทำ I / O) และกิจกรรมหนึ่งสามารถบล็อกได้
ใช้ "เครื่องรัฐเท่านั้น" ทางเลือกที่ทำงานได้กับหลายเธรดในภาษาระดับสูง?


4
คอมพิวเตอร์ยังเป็นเครื่องทัวริง อย่างไรก็ตามมันไม่จำเป็นต้องมีประโยชน์ในการตั้งโปรแกรมเหมือนเครื่องทัวริง สแตกในภาษาที่จำเป็นเป็นสิ่งที่มีประโยชน์อย่างมากและโปรแกรมแบบมัลติเธรดอนุญาตให้เก็บสแต็คจำนวนมากในหน่วยความจำในเวลาเดียวกัน การทำแบบเดียวกันในเครื่องจักรของรัฐนั้นเป็นไปได้อย่างแน่นอน แต่สิ่งที่ยุ่งเหยิงยิ่งกว่าเดิมทั้งหมด
thiton

10
Alan เป็นผู้พัฒนาเคอร์เนลระบบปฏิบัติการ นี่เป็นโดเมนของเขา ดังนั้นคำพูดของเขาควรถูกนำมาใช้ในบริบทนั้น เขาจะเขียนโปรแกรม 'เทียบกับโลหะ' ซึ่งมันสมเหตุสมผลมากกว่าที่จะใช้โมเดลดังกล่าว เมื่อระบบปฏิบัติการแยกส่วนประกอบของฮาร์ดแวร์ออกและส่วนประกอบภายในที่แท้จริง (นั่นคือ "คอมพิวเตอร์คือเครื่องสถานะ ... ") คุณมีโอกาสและประโยชน์ที่จะสามารถใช้รุ่นอื่น ๆ ที่เหมาะสมกับโดเมนของคุณมากขึ้น เกือบทุกเกมใช้งานเครื่องจักรของรัฐอย่างหนัก
Steven Evers

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

2
"แต่สิ่งที่เป็นนามธรรม [เธรด] ให้อินเทอร์เฟซที่ง่ายและผิดพลาดน้อยลง" ดูเหมือนว่าจะเป็นเท็จ จำนวนคนที่ใช้เธรดความปลอดภัยไม่ถูกต้องบ่งชี้ว่าดูเหมือนจะทำให้เกิดข้อผิดพลาด
S.Lott

1
ความคิดเห็นและคำตอบมากมายที่นี่ตีความหมายของคำพูดว่าเป็นการต่อต้านการทำงานหลายอย่างโดยทั่วไป ฉันเชื่อว่า Alan Cox เป็นเพียงการต่อต้านเธรดและจะสนับสนุนการใช้กระบวนการหลายอย่างเพื่อให้บรรลุเป้าหมายมากมายที่ผู้คนใช้สำหรับเธรด โปรดทราบว่าเขาเป็นแฮกเกอร์ Unix: fork FTW ฉันไม่ได้พบความคิดเห็นใด ๆ จากเขาโดยตรงจากคำพูด แต่นี่เป็นความคิดเห็นจาก Larry McVoy จากรายชื่อผู้รับจดหมาย Linux kernel ที่ไปในทิศทางนี้: lkml.indiana.edu/hypermail/linux/kernel/0106.2/0405.html
Martin B

คำตอบ:


25

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

บนคอมพิวเตอร์แบบแกนเดียวไม่มีอะไรเกิดขึ้น "ในเวลาเดียวกัน" มันเป็นเพียงการเรียกใช้แบบอินเตอร์เลด

มีหลายวิธีหลายวิธีในการบรรลุการสอดแทรก จำนวนมาก

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

  • T1- ก่อนการล็อค
  • T1- กับล็อค
  • T1- ล็อคหลังจาก
  • T2- ก่อนล็อค
  • T2- พร้อมล็อค
  • T2-after lock

[สิ่งนี้สามารถอยู่ในลูปหรือมีล็อคมากกว่าหรืออะไรก็ได้ ทั้งหมดนี้ใช้เวลานานขึ้นไม่ซับซ้อนมากขึ้น]

ขั้นตอนของ T1 จะต้องทำงานตามลำดับ (T1- ก่อน, T1- กับ, T1- หลัง) และขั้นตอนของ T2 จะต้องทำงานตามลำดับ (T2- ก่อน, T2-with, T2-after)

นอกเหนือจากข้อ จำกัด "ในการสั่งซื้อ" สิ่งเหล่านี้สามารถสอดแทรกในทางใดทางหนึ่ง อย่างไรก็ตาม. พวกเขาสามารถเรียกใช้ตามที่ระบุไว้ข้างต้น การสั่งซื้ออื่นที่ถูกต้องคือ (T1- ก่อน, T2- ก่อน, T2-lock, T1-lock, T2-after, T1-after) มีคำสั่งที่ถูกต้องมากมาย

รอ.

นี่เป็นเพียงกลไกของรัฐที่มีหกสถานะ

มันเป็นสถานะออโตมาต้าแบบไม่ จำกัด การจัดลำดับของสถานะ T1-xxx ด้วยสถานะ T2-xxx นั้นไม่แน่นอนและไม่สำคัญ ดังนั้นจึงมีสถานที่ที่ "สถานะถัดไป" คือการโยนเหรียญ

ตัวอย่างเช่นเมื่อ FSM เริ่มต้น T1-before หรือ T2-before เป็นสถานะแรกที่ถูกต้องตามกฎหมาย โยนเหรียญ

สมมติว่ามันมาก่อน T1 ทำอย่างนั้น. เมื่อทำเสร็จแล้วจะมีตัวเลือกระหว่าง T1-with และ T2-before โยนเหรียญ

ในแต่ละขั้นตอนใน FSM จะมีสองตัวเลือก (สองเธรด - สองตัวเลือก) และการโยนเหรียญสามารถกำหนดสถานะที่เฉพาะเจาะจงได้


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

5
เครื่องมัลติคอร์ทำให้การจัดตารางซับซ้อนขึ้นเล็กน้อย อย่างไรก็ตามแกนประมวลผลทั้งหมดเขียนไปยังหน่วยความจำทั่วไปเดียวดังนั้นหน่วยความจำเขียนคำสั่งระหว่างสองแกนหมายความว่า - โดยหลักแล้ว - เรากลับไปที่การประมวลผลหน่วยความจำแบบเขียนสลับกัน การหาประโยชน์จากระบบปฏิบัติการหลักและ JVM ใช้ประโยชน์จากสิ่งนี้ ไม่จำเป็นต้องคิดซ้ำเกี่ยวกับมัน
S.Lott

9

การเขียนฟังก์ชั่นการบล็อคมีไว้สำหรับผู้ที่ไม่สามารถสร้างเครื่องรัฐ)

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

คุณไม่สามารถใช้ฟังก์ชั่นการปิดกั้นในเครื่องสถานะ (อย่างน้อยหนึ่งที่ไม่ได้รับอนุญาตให้ "หยุด")

และใช่การใช้เครื่องรัฐเป็นทางเลือกที่ทำงานได้ ในระบบเรียลไทม์นี่เป็นทางเลือกเดียวคือระบบที่จัดทำเฟรมเวิร์กสำหรับเครื่อง การใช้เธรดและฟังก์ชั่นการปิดกั้นเป็นเพียง "วิธีง่าย ๆ " เพราะโดยปกติแล้วการเรียกไปยังฟังก์ชั่นการบล็อกหนึ่งครั้งจะเข้ามาแทนที่สถานะของเครื่องประมาณ 3-4 สถานะ


ความผิดพลาดของโค้ดเพจในโปรแกรมแบบ context-of-execution นั้นเป็นการบล็อกพื้นฐานอย่างแท้จริง ตามคำนิยามรหัสที่มีบริบทของการดำเนินการเพียงครั้งเดียวจะไม่สามารถดำเนินการไปข้างหน้าจนกว่าจะมีโค้ดอันถัดไปในโฟลว์พร้อมใช้งาน
David Schwartz

1
@ David Schwartz: จริงมันปิดกั้นพื้นฐาน แต่มันไม่ใช่ 'การทำงาน' เนื่องจากไม่ใช่สิ่งที่รหัสที่ถูกบล็อกทำนั้นเป็นสิ่งที่เกิดขึ้นกับมัน
Javier

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

1
@David Schwartz: คำจำกัดความของพฤติกรรม "การบล็อก" จะเป็นไปตามข้อกำหนด "แบบเรียลไทม์" เสมอ ตัวอย่างเช่น: ความผิดพลาดของโค้ดเพจถูกพิจารณาว่าไม่บล็อกสำหรับแอปพลิเคชันที่ต้องการการตอบสนองตามลำดับเป็นมิลลิวินาที ในทางตรงกันข้ามหากแอปพลิเคชันมีข้อกำหนดแบบเรียลไทม์ที่เข้มงวดจะไม่ใช้หน่วยความจำเสมือนเลย
MaR

1
@Mar: ... หรือใช้อัลกอริทึมการแลกเปลี่ยนที่กำหนดขึ้นเพื่อรับประกันการดึงข้อมูลที่จำเป็นก่อนที่จะจำเป็น
เอสเอฟ

9

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

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

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

ใช้ "เครื่องรัฐเท่านั้น" ทางเลือกที่ทำงานได้กับหลายเธรดในภาษาระดับสูง?

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

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

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

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

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

นั่นทำให้ฉันได้รับความคิดเห็นของ Cox: กระทู้ไม่ได้มีไว้สำหรับคนที่ไม่สามารถเขียนกลไกของรัฐเท่านั้น บางคนมีความสามารถในการทำเช่นนั้น แต่เลือกที่จะใช้เครื่องรัฐกระป๋อง (เช่นด้าย) ในความสนใจของการได้งานทำเร็วหรือมีความซับซ้อนน้อยลง


2

จะเกิดอะไรขึ้นถ้ามี 2 กิจกรรมที่ต้องดำเนินการ (ทำการคำนวณและทำ I / O) และกิจกรรมหนึ่งสามารถบล็อกได้

ดีฉันสุจริตไม่สามารถจินตนาการวิธีจัดการกับการบล็อก I / O โดยไม่ต้องเธรด มันเรียกว่าการปิดกั้น afterall waitเพียงเพราะรหัสที่จะเรียกมันจะต้องมี

ตามการอ่านอีเมล Cox ต้นฉบับของฉัน (ด้านล่าง) เขาชี้ให้เห็นว่าการทำเกลียวไม่ได้ดี ฉันหมายถึงจะเกิดอะไรขึ้นถ้ามีคำขอ I / O 100 รายการ 1000? 10000? Cox กำลังชี้ให้เห็นว่าการมีเธรดจำนวนมากอาจทำให้เกิดปัญหาร้ายแรง:

จาก: Alan Cox (alan@lxorguk.ukuu.org.uk)
วันที่: ศุกร์ 21 มกราคม 2000 - 13:33:52 EST

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

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

มีหลายกรณี Linux แน่นอนที่สุดไม่ช่วยสถานการณ์สะดุดตาบล็อก I / O อะซิงโครนัส

อลัน

แหล่งที่มา: การวิเคราะห์ที่น่าสนใจของเคอร์เนลลินุกซ์เธรดโดย IBM (คลังเก็บจดหมายเมลลินุกซ์เคอร์เนล)


1
  • ในทางทฤษฎีความจริงข้อนี้ ในชีวิตจริงเธรดเป็นเพียงนามธรรมที่มีประสิทธิภาพที่ใช้ในการเขียนโปรแกรมเครื่องรัฐ พวกมันมีประสิทธิภาพมากจนสามารถใช้ในการเขียนโปรแกรม Statecharts และ Petri nets ได้เช่นกัน (เช่นพฤติกรรมแบบขนาน

  • ปัญหากับเครื่องจักรของรัฐคือการระเบิดแบบ combinatorial จำนวนสถานะของคอมพิวเตอร์ที่มี 4G RAM คือ 2 ^ (2 ^ 32) สถานะ (ไม่นับดิสก์ไดรฟ์ 2T)

  • สำหรับผู้ชายที่มีเครื่องมือเพียงอย่างเดียวคือค้อนทุกปัญหาดูเหมือนเล็บ


1

เธรดเป็นตัวเลือกเดียวในสองกรณี:

  • เพื่อใช้หลายคอร์โดยไม่มีการแยกหน่วยความจำ
  • เพื่อรับมือกับโค้ดภายนอกที่บล็อก

ประการที่สองคือสาเหตุที่คนส่วนใหญ่คิดว่าเธรดไม่สามารถหลีกเลี่ยงได้สำหรับการทำ IO หรือการเขียนโปรแกรมเครือข่าย แต่โดยทั่วไปแล้วเพราะพวกเขาไม่รู้ว่าระบบปฏิบัติการของพวกเขามี API ขั้นสูงมากขึ้น (หรือไม่ต้องการต่อสู้กับการใช้งาน)

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


1
สิ่งที่ดีที่สุดของโลกทั้งสอง: ขนาดเล็กการบล็อกเครื่องจักรสถานะในเธรดทำให้เป็นรหัสแอปพลิเคชันที่ง่ายมาก และกระทู้ก็แยกกันเป็นแกนถ้าคุณมีแล้ว หากทุกอย่างไม่มีแกนอย่างน้อยสองแกนมันก็จะเร็ว เช่นโทรศัพท์ที่ใช้แขน quad core มา 2012
Tim Williscroft

0

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

while (true) {
    switch (event) {
        case ButtonPressed:
        ...
        case MachineIsBurning:
        ....
    }
}

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

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

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

ดังนั้นเพื่อตอบคำถามสุดท้าย: ใช่เครื่องรัฐเป็นอีกทางเลือกหนึ่ง GUI ส่วนใหญ่ทำงานในลักษณะเดียวกันกับเธรด GUI อย่าเพิ่งผลักเครื่องสถานะไกลเกินไป


0

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

สิ่งที่เป็นนามธรรมของการใช้เธรดทำให้ระบบขนานที่ซับซ้อนมากขึ้นง่ายต่อการใช้งาน แต่ในที่สุดระบบขนานทั้งหมดมีปัญหาเดียวกันที่ต้องจัดการ ปัญหาคลาสสิกเช่นการหยุดชะงัก / Livelockและผกผันความสำคัญเป็นเพียงเป็นไปได้ด้วยตามระบบกลไกของรัฐที่พวกเขาจะมีขนานหน่วยความจำที่ใช้ร่วมกัน , NUMAหรือแม้แต่ระบบที่ใช้ CSPหากมีความซับซ้อนเพียงพอ


0

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

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

บางกรณีเครื่องของรัฐจะเป็นตัวเลือกที่ดีกว่า - ฉันกำลังคิดถึงสิ่งที่ฝังอยู่ในขณะนี้ซึ่งมีการใช้รูปแบบของเครื่องรัฐและใช้ซ้ำ ๆ และในลักษณะที่เป็นทางการมากขึ้น (เช่นวิศวกรรมที่เหมาะสม :))

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

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


2
เครื่องจักรของรัฐไม่ซับซ้อนเลย! เครื่องจักรของรัฐที่ซับซ้อนมีความซับซ้อน แต่เป็นระบบที่ซับซ้อนทั้งหมด: o)
MaR

2
-1 สำหรับ "อย่าลอง" นั่นคือคำแนะนำที่แย่ที่สุดที่คุณสามารถให้ได้
Javier

1
-1 "อย่าลอง"? นั่นเป็นเพียงความโง่เขลา ฉันจะท้าทายการยืนยันของคุณว่าเครื่องจักรของรัฐนั้นยาก เมื่อคุณเข้าสู่บางสิ่งบางอย่างเช่น Heirarchal Fuzzy State Machine ... จากนั้นใช่แล้วมันค่อนข้างซับซ้อน แต่เครื่องรัฐง่าย ๆ นั่นเป็นสิ่งที่ค่อนข้างพื้นฐานที่ทุก ๆ ปีที่ 2 เรียนรู้เมื่อฉันอยู่ในโรงเรียน
Steven Evers

ขอผมใช้ถ้อยคำใหม่หน่อย 'อย่าลอง' หน่อย ...
gbjbaanb

0

ตัวอย่างที่ดีของการใช้งานเครื่องรัฐที่เหมาะสมแทนกระทู้: nginx vs apache2 โดยทั่วไปคุณสามารถสมมติว่า nginx จัดการการเชื่อมต่อทั้งหมดในหนึ่งเธรด apache2 สร้างเธรดต่อการเชื่อมต่อ

แต่สำหรับฉันแล้วการใช้ state machines vs threads นั้นค่อนข้างคล้ายคลึงกันโดยใช้ asm vs java ที่ออกแบบมาอย่างสมบูรณ์แบบด้วยมือคุณอาจจะได้ผลลัพธ์ที่เพิ่มขึ้น แต่มันต้องใช้ความพยายามของโปรแกรมเมอร์เป็นจำนวนมากมีวินัยมากทำให้โครงการมีความซับซ้อนมากขึ้น โปรแกรมเมอร์อื่น ๆ มากมาย ดังนั้นหากคุณเป็นคนหนึ่งที่ต้องการสร้างเว็บเซิร์ฟเวอร์ที่รวดเร็ว - ใช้ state machins และ async IO หากคุณกำลังเขียนโครงการ (ไม่ใช่ห้องสมุดที่จะใช้ทุกที่) - ใช้เธรด

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