สภาพแวดล้อมรันไทม์สามารถตรวจจับลูปไม่สิ้นสุดได้หรือไม่


19

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

สำหรับวัตถุประสงค์ของคำถามนี้ฉันกำหนด "infinite loop" เพื่อหมายถึงชุดคำสั่งและข้อมูลสแต็คเริ่มต้น / กองที่เกี่ยวข้องซึ่งเมื่อดำเนินการแล้วให้ส่งคืนกระบวนการกลับสู่สถานะเดิม (รวมถึงข้อมูล) เหมือนเดิม เริ่มการวนซ้ำไม่สิ้นสุด (กล่าวอีกนัยหนึ่งโปรแกรมที่สร้างการขยายทศนิยมแบบไม่มีกำหนดระยะยาวของ pi จะไม่ "ติด" ใน "infinite loop" เนื่องจากในการวนซ้ำทุกครั้งจะมี pi จำนวนมากขึ้นในหน่วยความจำที่เกี่ยวข้อง)

(พอร์ตจาก/programming//q/16250472/1858225 )



ฉันไม่คิดอย่างนั้น ไม่มีข้อ จำกัด ในอินพุต
Kyle Strand

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

@Benj stackoverflow.com/q/16249785/1858225คำถามเดิม (ซึ่งไม่ใช่ของฉัน) เป็นเรื่องเกี่ยวกับสภาพแวดล้อมรันไทม์จริง (หรือมากกว่าเกี่ยวกับระบบปฏิบัติการ) แม้ว่ามันจะปิดไปแล้วดังนั้นฉันจึงเขียนใหม่ฉันเปลี่ยนโฟกัสไปทางด้านทฤษฎี
Kyle Strand

ตกลง. วิธีเดียวที่ฉันเห็นคือการสุ่มตัวอย่างจุดสำคัญบางอย่างและทำการแฮชของพวกเขา (ซึ่งอาจเป็นบรรทัดสุดท้ายของเอาต์พุตบันทึกหรือสถานะ CPU บางอย่างเช่นสแต็ก ptr) และเก็บแฮชของชุดโพรบ (ชุด ในเวลาที่กำหนด) ในเครือมาร์คอฟ จากนั้นคุณจะสามารถ (โดยเลือก "โพรบ" ที่ถูกต้อง) เพื่อตรวจจับการล็อกแบบวน ฉันยังคิดถึงการเชื่อมโยงไลบรารีระบบเข้ากับและใช้รายการเป็นโพรบ สนุก ;)
Benj

คำตอบ:


11

อาจเป็นไปได้ในทางทฤษฎีสำหรับสภาวะแวดล้อมรันไทม์เพื่อตรวจสอบลูปดังกล่าวโดยใช้โพรซีเดอร์ต่อไปนี้:

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

ในความเป็นจริงแทนที่จะทำการตรวจสอบนี้หลังจากทุกคำสั่งเดียวสภาพแวดล้อมรันไทม์สามารถหยุดกระบวนการชั่วคราวเป็นระยะและทำให้ประหยัดสถานะ หากกระบวนการติดอยู่ในการวนซ้ำไม่สิ้นสุดที่เกี่ยวข้องกับn state จากนั้นหลังจากการตรวจสอบn ครั้งส่วนใหญ่จะมีการตรวจสอบสถานะที่ซ้ำกัน

หมายเหตุแน่นอนว่านี่ไม่ใช่วิธีแก้ไขปัญหาการหยุดชะงัก ความแตกต่างจะกล่าวถึงที่นี่

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

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


8
มันเป็นไปได้ (อย่างน้อยในโลกอุดมคติของเครื่องทัวริงและเช่น) ที่โปรแกรมจะเข้าสู่วง จำกัดได้โดยไม่ต้องทำซ้ำรัฐ ลองนึกถึงบางสิ่งบางอย่างเช่น C loopfor(i = 0; ; i++) ;
vonbrand

nn<nn+1

@ vonbrand, loop เฉพาะนั้นไม่ตรงกับคำจำกัดความของ "loop" สำหรับจุดประสงค์ของคำถามเฉพาะนี้ (ซึ่งเป็นสาเหตุที่ทำให้คำจำกัดความของฉันชัดเจนในคำถามนั้น)
Kyle Strand

n

บางทีฉันอาจไม่เข้าใจคำถามของคุณ ฉันคิดว่าคุณต้องการที่จะรู้ว่ามันเป็นไปได้ที่จะตัดสินใจว่าโปรแกรมใด ๆซ้ำสถานะ คุณเพิ่งถามว่ามันเป็นไปได้ที่จะตัดสินใจว่าบางโปรแกรมทำซ้ำสถานะ?
Huck Bennett

6

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

ภายใต้สมมติฐานที่ไม่น่าจะเป็นไปได้สูง แต่ไม่มีข้อ จำกัด ในทางทฤษฎีเราสามารถทำซ้ำโปรแกรมและรันโปรแกรมในสองช่วงเวลาแยกกัน แต่ละคนจะทำการคำนวณเดียวกัน

งั้นลองทำดู เราจะเรียกใช้ครั้งเดียวในรันไทม์ของ Tortoise และในเวลาเดียวกันเราจะเรียกใช้ในรันไทม์ของ Hare อย่างไรก็ตามเราจะจัดการให้รันไทม์ของ Hare ทำงานเร็วเป็นสองเท่า ทุกครั้งที่รันไทม์ของ Tortoise สร้างเพียงหนึ่งขั้นตอนรันไทม์ของ Hare จะทำสองขั้นตอน

ตอนนี้เราสามารถเปรียบเทียบสถานะหลังจากทุกขั้นตอนของ Tortoise runtime หากโปรแกรมเข้าสู่วงวนไม่รู้จบn ขั้นตอนหลังจากคำนำหน้าบางส่วนที่ไม่ใช่ลูป พี ขั้นตอนจากนั้นรัฐกระต่ายและเต่าจะเหมือนกันในทุกขั้นตอนของเต่า kn สำหรับจำนวนเต็มใด ๆ k ที่ไหน knพี.

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

ตามเงื่อนไขที่ฉันใช้บ่งบอกว่านี่เป็นเพียงอัลกอริทึมTortoise และ Hare cycle-detection ที่มีชื่อเสียงของ Robert Floyd


3

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

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

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

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

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


2

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

เท่าที่ฉันรู้ว่ามีไม่มากในการตรวจสอบการเลิกจ้างจริงสำหรับภาษาทั่วไป

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