วิธี จำกัด เวลาที่โปรแกรมรันใน Linux?


10

python simulate.py <parameter list>ฉันมีหลายแบบจำลองในการทำแต่ละถูกเรียกด้วย ปัญหาเกี่ยวกับการจำลองเหล่านี้คือบางส่วนหยุดทำงานโดยไม่ต้องพูดถึงซึ่งทำให้ฉันไม่สามารถเรียกใช้งานเป็นชุดด้วยสคริปต์อย่างง่าย

สิ่งที่ฉันต้องการคือรูปแบบของคำสั่ง "รันไทม์ - ข้อ จำกัด " ซึ่งจะฆ่ากระบวนการโดยอัตโนมัติ (ควรกดCtrl + C จริงๆ แต่ฉันคิดว่าการฆ่าแบบง่ายจะทำได้เช่นกัน) หลังจากเวลาที่กำหนดถ้า กระบวนการไม่ได้สิ้นสุดอย่างสง่างาม

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

คำตอบ:


15

โซลูชั่นที่มีศักยภาพ # 1

ใช้timeoutคำสั่ง:

$ date
Mon May  6 07:35:07 EDT 2013
$ timeout 5 sleep 100
$ date
Mon May  6 07:35:14 EDT 2013

คุณสามารถใส่ตัวป้องกันเข้าไปในtimeoutคำสั่งรวมถึงkillกระบวนการหากมันไม่ได้หยุดหลังจากผ่านไประยะหนึ่ง

$ date
Mon May  6 07:40:40 EDT 2013
$ timeout -k 20 5 sleep 100
$ date
Mon May  6 07:40:48 EDT 2013

ขั้นตอนนี้จะรอนานถึง 20 วินาทีหลังจากกระบวนการsleep 100หยุดทำงานหากยังคงทำงานอยู่จากนั้นtimeoutจะส่งkillสัญญาณ

โซลูชันที่เป็นไปได้ # 2

ทางเลือกอื่นแม้ว่าวิธีที่มีความเสี่ยงมากกว่านั้นจะเป็นดังนี้

./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"

พบเทคนิคนี้ในกองมากเกินในคำถามหัวข้อ: การ จำกัด เวลาโปรแกรมวิ่งในลินุกซ์ โดยเฉพาะนี้คำตอบ

หมายเหตุ:ตามความคิดเห็นที่เหลือโดย @mattdm วิธีการข้างต้นอาจมีความเสี่ยงเนื่องจากทำให้สันนิษฐานว่าไม่มีกระบวนการใหม่ใด ๆ ที่เริ่มต้นตั้งแต่กระบวนการของคุณ ดังนั้นจึงไม่มีการกำหนดหมายเลข PID ใหม่ ด้วยวิธีนี้ไม่ควรใช้วิธีนี้ แต่เป็นเพียงข้อมูลอ้างอิงสำหรับแนวทางทั่วไปของปัญหา timeoutวิธีการเป็นตัวเลือกที่ดีของทั้ง 2


แต่จะรับประกันได้ว่าสคริปต์จะใช้เวลาตลอดเวลา ในกรณีของฉันมันไม่ได้ 1 วินาที แต่ค่อนข้าง 15 นาที
Adam Ryczkowski

แต่วิธีแก้ปัญหาอื่นที่พบในคำถามนั้นควรเป็นสิ่งที่ฉันต้องการ ขอบคุณ!
Adam Ryczkowski

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

1
@ MichaelKjörlingขอบคุณสำหรับการคืนเงิน ฉันได้อัปเดตคำตอบของฉันตามความคิดเห็นเดียวกับที่ OP ทิ้งไว้เช่นกัน ดูเหมือนว่าtimeoutคำสั่งจะทำในสิ่งที่เขากำลังมองหาอย่างแน่นอนรอ OP เพื่อตอบรับความคิดเห็นของฉัน
slm

@slm timeoutควรเป็นคำตอบที่ฉันต้องการ ฉันกำลังทดสอบอยู่ในขณะนี้
Adam Ryczkowski

4

ฉันพบบางสิ่งที่ดีกว่าเล็กน้อยtimeout: timelimit.

มันมีข้อดีหลายประการ หนึ่งคือผู้ใช้ที่สามารถยกเลิกการดำเนินการด้วยตนเองโดยการกด "Ctrl + C"

timelimitโปรแกรมสามารถใช้ได้ในพื้นที่เก็บข้อมูล Debian


1
พยายามเข้าใจความแตกต่างของเวลาและการหมดเวลา การหมดเวลาสามารถหยุดได้ด้วย Ctrl + C ข้อดีอื่น ๆ คืออะไร?
slm

หมดเวลาของฉันไม่สามารถ ฉันใช้ Mint 14 (อ้างอิงจาก Ubuntu Quantal)
Adam Ryczkowski

3

คุณสามารถปรับเวลา cpu และสิ่งอื่น ๆ ด้วยulimitสำหรับเวลา cpu โดยเฉพาะ:

$ ulimit -t 60      # limit to 60 seconds
$ program

เห็นนี้ U & L Q & A: unix.stackexchange.com/a/4666/7453 @Gilles ให้ภาพรวมที่ดีเกี่ยวกับการใช้ ulimit สำหรับวัตถุประสงค์นี้
slm

0

Bash ใช้ตัวแปรที่เรียกว่า$BASHPIDสามารถใช้ในสถานการณ์เช่นนี้:

#!/bin/bash
do_face() {
    local parent=$1
    echo $BASHPID > pid
    sleep 10
    echo "Killing parent $parent"
    kill $parent
}

ME=$BASHPID
eval $(echo "do_face $ME &")
sleep 20 && kill $(cat pid) && echo "killed child $(cat pid)"
exit 1

คุณสามารถเปลี่ยนข้อโต้แย้งในการเรียกไปsleepในdo_face()การ100แทน10และดูสิ่งที่เกิดขึ้นเมื่อเด็กใช้เวลานานเกินไปที่จะทำของเขาเหลือเกิน เพียงแค่เปลี่ยนการเรียกไปยังโหมดสลีปdo_face()เป็นการเรียกใช้งานของคุณและถ้าใช้เวลานานเกินไปสคริปต์จะฆ่ามัน20วินาทีคือค่า จำกัด ในตัวอย่างนี้ พารามิเตอร์สามารถนำมาใช้เพื่อให้มันกลายเป็นสคริปต์ที่ง่ายต่อการโทรและสามารถเรียกโดยสคริปต์อื่นในชุดหรืออะไรก็ตาม การจัดการไฟล์ pid สำหรับแต่ละกระบวนการที่เกิดขึ้นพร้อมกันนั้นเป็นปัญหาที่ต้องได้รับการจัดการบางทีอาจใช้ dirs ย่อยต่างกัน ...

หมายเหตุ: บน GNU Linux sleepสามารถใช้อาร์กิวเมนต์จุดลอยเช่นsleep 0.1หลับเป็นเวลาสิบในวินาที

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