kill#
Αποστολή σήματος σε λίστα διεργασιών.
Η kill είναι η εμπρόσθια διεπαφή της Perl για την κλήση συστήματος kill(2). Παραδίδει το SIGNAL σε κάθε διεργασία που προσδιορίζεται από τη LIST και επιστρέφει τον αριθμό των ορισμάτων στα οποία στάλθηκε επιτυχώς σήμα. Είναι επίσης ο τυπικός τρόπος να ρωτήσετε τον πυρήνα «υπάρχει ακόμα αυτό το PID και μπορώ να του στείλω σήμα;» χωρίς να ενοχλήσετε πραγματικά τον στόχο, μέσω της μορφής signal-zero.
Σύνοψη#
kill SIGNAL, LIST
kill SIGNAL # tainting side-effect only; returns 0
Τι επιστρέφεται#
Ο αριθμός των ορισμάτων στη LIST που πέρασαν επιτυχώς στην kill(2). Αυτός δεν είναι απαραίτητα ο αριθμός των διεργασιών που πραγματικά έλαβαν το σήμα - όταν το SIGNAL είναι αρνητικό, ή όταν ένα PID προσδιορίζει ομάδα διεργασιών, ένα όρισμα μπορεί να στοχεύει πολλές διεργασίες. Σε σφάλματα δικαιωμάτων ή «δεν υπάρχει τέτοια διεργασία» για ένα όρισμα, αυτό το όρισμα δεν μετράται και η $! τίθεται στο αντίστοιχο errno (EPERM, ESRCH, EINVAL).
my $cnt = kill 'HUP', $child1, $child2;
kill 'KILL', @goners;
Με κενή LIST, δεν στέλνεται κανένα σήμα και η τιμή επιστροφής είναι 0. Η σκέτη μορφή kill SIGNAL γράφεται μερικές φορές αμιγώς για να πυροδοτήσει ελέγχους taint στο SIGNAL· δείτε το perlsec.
SIGNAL: όνομα ή αριθμός#
Το SIGNAL μπορεί να είναι είτε όνομα σήματος (συμβολοσειρά) είτε αριθμός σήματος. Η μορφή συμβολοσειράς συνιστάται για φορητότητα επειδή το ίδιο σήμα μπορεί να έχει διαφορετικούς αριθμούς σε διαφορετικά λειτουργικά συστήματα.
Ένα όνομα σήματος μπορεί να φέρει το πρόθεμα SIG ή όχι - τα 'TERM' και 'SIGTERM' ονοματίζουν το ίδιο σήμα.
kill 'TERM', $pid; # portable
kill 'SIGTERM', $pid; # also fine
kill 15, $pid; # SIGTERM on Linux; may differ elsewhere
kill 9, $pid; # SIGKILL on Linux
Η λίστα ονομάτων σημάτων διαθέσιμων στην τρέχουσα πλατφόρμα βρίσκεται στο $Config{sig_name}, που παρέχεται από το άρθρωμα Config.
SIGNAL 0: έλεγχος ζωντάνιας#
Αν το SIGNAL είναι ο αριθμός 0 ή η συμβολοσειρά 'ZERO' (ή 'SIGZERO'), κανένα σήμα δεν παραδίδεται πραγματικά. Η kill(2) εξακολουθεί να εκτελεί τον έλεγχο δικαιωμάτων της, οπότε η κλήση σας λέει αν θα ήταν δυνατό να σταλεί σήμα στη διεργασία - δηλαδή, η διεργασία υπάρχει και ανήκει στον ίδιο χρήστη, ή ο καλών είναι ο super-user.
if (kill 0, $pid) {
# process exists and we may signal it
}
elsif ($!{ESRCH}) {
# no such process - it has exited and been reaped
}
elsif ($!{EPERM}) {
# it exists but we are not allowed to signal it
}
Αυτό είναι το κανονικό ιδίωμα για τον έλεγχο ότι ένα παιδί είναι ακόμα ζωντανό, ακόμη και ως zombie, και δεν έχει αλλάξει το UID του. Δεν συλλέγει το παιδί - χρησιμοποιήστε την waitpid γι” αυτό.
Αρνητικό SIGNAL: σήμα σε ομάδα διεργασιών#
Ένα αρνητικό όνομα ή αριθμός σήματος στέλνει σήμα σε ολόκληρη ομάδα διεργασιών αντί σε μεμονωμένη διεργασία. Οι kill '-KILL', $pgrp και kill -9, $pgrp στέλνουν αμφότερες SIGKILL σε κάθε διεργασία της ομάδας που προσδιορίζεται από το $pgrp.
kill '-TERM', $pgrp; # polite shutdown of the whole group
kill -9, $pgrp; # forced
Τα θετικά σήματα είναι σχεδόν πάντα αυτό που θέλετε. Καταφύγετε σε αρνητικό σήμα μόνο όταν ο στόχος είναι σκόπιμα αρχηγός ομάδας διεργασιών (για παράδειγμα ένα παιδί που τοποθετήσατε στη δική του ομάδα με setpgrp ώστε να τερματίσετε το υποδέντρο μονομιάς).
PID 0, αρνητικά PIDs#
Η συμπεριφορά της kill όταν ένα PID είναι μηδέν ή αρνητικό εξαρτάται από το λειτουργικό σύστημα. Σε συστήματα συμμορφούμενα με POSIX (συμπεριλαμβανομένου του Linux):
PID
0- αποστολή σήματος στην ίδια την ομάδα διεργασιών του αποστολέα.PID
-1- αποστολή σήματος σε κάθε διεργασία στην οποία ο καλών έχει δικαίωμα να στείλει σήμα (super-user: όλο το σύστημα, μείον μερικά ειδικά PIDs).Οποιοδήποτε άλλο αρνητικό PID - συμπεριφέρεται όπως αρνητικό
SIGNALστην απόλυτη τιμή: αποστολή σήματος στην ομάδα διεργασιών της οποίας το PGID ισούται μεabs(PID).
Αν τόσο το SIGNAL όσο και το PID είναι αρνητικά, το αποτέλεσμα δεν είναι ορισμένο· μια μελλοντική Perl μπορεί να προειδοποιήσει. Μη συνδυάζετε τα δύο.
Παραδείγματα#
Ευγενική αίτηση σε ένα παιδί να τερματίσει, και έπειτα κλιμάκωση:
kill 'TERM', $child;
sleep 2;
kill 'KILL', $child if kill 0, $child;
waitpid $child, 0;
Καμία συλλογή, απλώς έλεγχος αν ένα αρχείο PID ονοματίζει ακόμα ζωντανή διεργασία:
open my $fh, "<", "/run/daemon.pid" or die $!;
chomp(my $pid = <$fh>);
close $fh;
if (kill 0, $pid) {
print "daemon alive (pid $pid)\n";
} else {
print "stale pid file: $!\n";
unlink "/run/daemon.pid";
}
Αποστολή σήματος σε ολόκληρη ομάδα διεργασιών που δημιουργήθηκε από ένα παιδί σωλήνωσης κελύφους:
my $pgrp = getpgrp($child);
kill '-TERM', $pgrp;
Εγκατάσταση χειριστή και αποστολή σήματος στον εαυτό σας:
local $SIG{USR1} = sub { warn "got USR1\n" };
kill 'USR1', $$; # $$ is our own PID
Εκπομπή σε πολλούς εργάτες και ανακάλυψη πόσοι ήταν προσβάσιμοι:
my @workers = (1234, 1235, 9999); # 9999 has exited
my $hit = kill 'HUP', @workers; # probably 2
warn "lost a worker: $!\n" if $hit < @workers;
Οριακές περιπτώσεις#
Κενή LIST: η
kill 'TERM'δεν στέλνει τίποτα και επιστρέφει0. Η κλήση εξακολουθεί να αποτιμά τοSIGNAL, που είναι ο μόνος λόγος να τη γράψετε (διάδοση taint).Άγνωστο όνομα σήματος: εγείρει εξαίρεση (
Unrecognized signal name "FOO"). Επαληθεύστε έναντι του$Config{sig_name}αν το όνομα προέρχεται από είσοδο χρήστη.Η
$!μετά από μερική επιτυχία: ηkillδιασχίζει τηLISTαπό αριστερά προς τα δεξιά. Η$!αντικατοπτρίζει το τελευταίο όρισμα που απέτυχε, όχι όλα. Αν χρειάζεστε σφάλματα ανά PID, καλέστε τηνkillμία φορά ανά PID.Τα zombies εξακολουθούν να μετρούν ως ζωντανά: η
kill 0, $zombie_pidεπιστρέφει αληθές μέχρι το παιδί να συλλεχθεί μεwaitήwaitpid. Αυτό συνήθως είναι αυτό που θέλετε για έλεγχο ζωντάνιας· περιστασιακά εκπλήσσει.Η παράδοση σήματος είναι ασύγχρονη: μια επιτυχημένη
killσημαίνει μόνο ότι το σήμα μπήκε σε ουρά. Ο χειριστής στο%SIGστη λαμβάνουσα διεργασία μπορεί να τρέξει αργότερα, και η μηχανική ασφαλών σημάτων της Perl αναβάλλει την παράδοση στο επόμενο όριο opcode.Αποστολή στον εαυτό σας: η
kill SIGNAL, $$λειτουργεί και είναι ο συνηθισμένος τρόπος για να δοκιμάσετε τους δικούς σας χειριστές%SIG.Καμία LIST, με taint: υπό
-T, η γραφήkill 'TERM'διαδίδει την tainted κατάσταση του'TERM'για την παρενέργεια ενεργοποίησης του ελέγχου - η μορφή δεν έχει άλλη χρήση.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
fork- δημιουργία της θυγατρικής διεργασίας στην οποία θα στείλετε αργότερα σήμαwait- συλλογή οποιουδήποτε τερματισμένου παιδιού, εκκαθαρίζοντας zombies που ηkill 0θα ανέφερε ακόμα ως ζωντανάwaitpid- συλλογή συγκεκριμένου παιδιού, προαιρετικά χωρίς μπλοκάρισμα (WNOHANG) ώστε να συνδυάζεται καθαρά με τηνkill 0getpgrp/setpgrp- επιθεώρηση και αλλαγή συμμετοχής σε ομάδα διεργασιών, που είναι αυτό στο οποίο λειτουργεί ηkillμε αρνητικό SIGNAL%SIG- εγκατάσταση χειριστών για τα σήματα που στέλνετε με τηνkillperlipc- πλήρης πραγμάτευση σημάτων, χειριστών και σημασιολογίας ασφαλών σημάτων