Πως κανω 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