Πως κανω kill ενα process μετα απο συγκεκριμενο χρονικο διαστημα
Giorgos Keramidas
keramida at ceid.upatras.gr
Tue Sep 30 02:37:59 EEST 2008
On Mon, 29 Sep 2008 17:12:01 +0300, Lysimachos Zografos <lzografos at gmail.com> wrote:
> Καλησπερα.
>
> Δεν μπορουσα να βρω καλυτερο topic για την ερωτηση. Το προβλημα μου
> ειναι το εξης:
>
> Εχω ενα binary (εστω "hrg") το οποιο κανει train ενα monte carlo. Δεν
> σταματαει μετα απο καποιο cutoff, απλα συνεχιζει μεχρι να το σκοτωσεις
> με ctrl+c. Θελω να τρεξω αυτο το binary με ν διαφορετικα input files
> (εστω file1.txt , file2.txt, file3.txt). Πως συνατασεται στο terminal
> (οχι με PERL/PYTHON etc) κατι που θα εκανε
>
> ./hrg -i file1.txt // τρεξε για 5 ωρες & kill // ./hrg -i
> file2.txt // τρεξε για 5 ωρες & kill // ./hrg -i
> file3.txt // τρεξε για 5 ωρες & kill
>
> Ελπιζω να γινομαι ανιτληπτος, αν οχι ειμαι προθυμος να εξηγησω καλυτερα.
Το καλύτερο που έχεις να κάνεις είναι κάτι με `control process':
./forker.py -t 18000 ./hrg -i file1.txt
Το parent process κάνει fork() & exec() το child process, και ύστερα
ρυθμίζει ένα alarm timer για X seconds. Αν ο timer κάνει expire πριν το
child process τερματίσει, το σκοτώνει με το ζόρι.
Αν προσπαθήσεις να το κάνεις όλο αυτό με shell scripting, θα φας τα
νιάτα σου προσπαθώντας να μαντέψεις τι process ID έχει το child process,
θα κάνεις χακιές πάνω από χακιές με έξτρα σάλτσα από χακεμένες χακιές,
θα βαρεθείς και θα το παρατήσεις.
Σε κάποια πιο 'high level' γλώσσα όμως, μπορείς να γράψεις πράγματα όπως:
#!/usr/bin/env python
import getopt
import os
import signal
import subprocess
import sys
# Pull over some useful functions from other namespaces.
exit = sys.exit
# Save the invocation name of the script, for later use.
progname = os.path.basename(sys.argv[0])
# Wait time. The number of seconds to wait for a subprocess, before we kill
# it ourselves. Set to 300 seconds by default, but may be overriden by the
# '-t command line option.
wtime = 300
def usage():
"""Print a usage message, and exit."""
print "usage: %s [-t TIMEOUT] cmd [args]" % progname
exit(1)
def parsewait(t):
"""Parse an integer valued `wait time', and update our internal
`wtime' timeout value."""
tmp = None
try:
tmp = int(t)
except ValueError, inst:
pass
if not tmp:
print "invalid wait time; using default (%d seconds)" % wtime
return tmp or wtime
def alarm(signo, frame):
raise Warning, "Timed out!"
def spawn(w, args):
"""Spawn a command; then wait for `w' seconds, and if the command is
still running, kill the subprocess."""
if not w or not args:
return None
try:
# Run args[] as a subprocess.
proc = subprocess.Popen(args)
# Set up an alarm signal to fire in `w' seconds.
signal.signal(signal.SIGALRM, alarm)
signal.alarm(w)
# If the alarm hasn't fired yet, gather the exit status of the
# subprocess and exit normally.
pid, sts = os.waitpid(proc.pid, 0)
signal.signal(signal.SIGALRM, signal.SIG_IGN)
except Warning, inst:
print "%s" % str(inst)
if proc:
os.kill(proc.pid, signal.SIGTERM)
return None
except OSError, inst:
print "%s: %s" % (args[0], str(inst))
return None
return (pid, sts)
if __name__ == "__main__":
try:
opts, args = getopt.getopt(sys.argv[1:], 't:')
except getopt.GetoptError, err:
usage()
# Go through the list of command-line options, and tune the globals
# which affect the behavior of the script accordingly.
for o, v in opts:
if o == '-t':
wtime = parsewait(v)
else:
assert False, "Unhandled option `%s'" % o
if args:
spawn(wtime, args)
exit(0)
Με αυτό το Python script ως `launcher' μπορείς να γράψεις κάτι σαν:
./launch.py -t 3600 ./lala foo bar baz
Η spawn() function του Python script ρυθμίζει ένα SIGALRM κι αν προλάβει
να κάνει fire, τυπώνει "Timed out!" και τερματίζει το child process με
το signal SIGTERM.
More information about the Linux-greek-users
mailing list