Διεργασίες

setpgrp#

Ορίζει την ομάδα διεργασιών μιας διεργασίας.

Η setpgrp μετακινεί τη διεργασία που αναγνωρίζεται από το PID στην ομάδα διεργασιών που αναγνωρίζεται από το PGRP. Ένα PID ίσο με 0 σημαίνει την τρέχουσα διεργασία· ένα PGRP ίσο με 0 σημαίνει «χρησιμοποίησε το PID ως το νέο id ομάδας» - δηλαδή, κάνε τη διεργασία αρχηγό ομάδας. Χωρίς ορίσματα παίρνει προεπιλογή setpgrp(0, 0), που κάνει την τρέχουσα διεργασία αρχηγό μιας νέας ομάδας διεργασιών της οποίας το id ισούται με το δικό της pid.

Αυτή είναι η διεπαφή Perl προς την υποκείμενη κλήση συστήματος setpgid(2) / setpgrp(2). Είναι το δομικό στοιχείο για την αποσύνδεση μιας διεργασίας από το ελέγχον τερματικό της και για σχήματα ελέγχου εργασιών που θέλουν να στείλουν σήματα σε ολόκληρη ομάδα ταυτόχρονα με την kill.

Σύνοψη#

setpgrp PID, PGRP
setpgrp            # same as setpgrp(0, 0)

Τι επιστρέφεται#

1 σε επιτυχία, undef σε αποτυχία με την $! τεθειμένη στον λόγο (συνήθως EPERM όταν η διεργασία-στόχος δεν είναι ο καλών ή παιδί του καλούντος, ή ESRCH όταν δεν υπάρχει τέτοια διεργασία). Ελέγξτε την τιμή επιστροφής - η σιωπηλή συνέχιση με μια διεργασία που εξακολουθεί να βρίσκεται στην παλιά ομάδα δεν είναι σχεδόν ποτέ αυτό που θέλετε.

setpgrp(0, 0)
    or die "setpgrp failed: $!";

Καθολική κατάσταση που επηρεάζει#

  • $! - τίθεται στην τιμή errno σε αποτυχία. Δεν αγγίζεται σε επιτυχία.

Παραδείγματα#

Αποσπάστε την τρέχουσα διεργασία σε δική της νέα ομάδα διεργασιών. Αυτό είναι το κλασικό πρώτο βήμα μιας ακολουθίας daemonisation, που τρέχει μετά τη fork και πριν το κλείσιμο των τυπικών handles:

setpgrp(0, 0)
    or die "setpgrp failed: $!";

Μετακινήστε ένα μόλις δημιουργηθέν παιδί στη δική του ομάδα ώστε ένα SIGTERM που στέλνεται στην ομάδα να σκοτώσει το παιδί και τυχόν εγγόνια που δημιουργεί, χωρίς να αγγίξει τον γονέα:

my $pid = fork // die "fork: $!";
if ($pid == 0) {
    setpgrp(0, 0) or die "setpgrp: $!";
    exec @cmd or die "exec: $!";
}
# parent: signal the whole group with a negative pid
kill 'TERM', -$pid;

Διαβάστε το id ομάδας πίσω μετά τον ορισμό του, χρησιμοποιώντας την getpgrp:

setpgrp(0, 0) or die $!;
my $pgid = getpgrp(0);
print "now leader of group $pgid\n";

Χειριστείτε τη λειτουργία αποτυχίας φορητότητας - σε πλατφόρμα χωρίς την υποκείμενη κλήση συστήματος η συνάρτηση εγείρει εξαίρεση αντί να επιστρέφει undef:

eval { setpgrp(0, 0) };
if ($@) {
    warn "no process-group support on this platform: $@";
}

Οριακές περιπτώσεις#

  • Η μορφή χωρίς ορίσματα παίρνει προεπιλογή (0, 0). Η γραφή setpgrp; είναι η ίδια με setpgrp(0, 0) - κάνει την τρέχουσα διεργασία νέο αρχηγό ομάδας. Η μορφή χωρίς ορίσματα είναι η φορητή μορφή (δείτε παρακάτω).

  • Συμβατότητα BSD 4.2. Η ιστορική setpgrp του BSD 4.2 δεν έπαιρνε ορίσματα. Σενάρια που πρέπει να τρέχουν σε τέτοια συστήματα μπορούν να βασιστούν μόνο στις μορφές setpgrp(0, 0) / setpgrp()· κάθε άλλος συνδυασμός ορισμάτων είναι μη φορητός.

  • Εγείρει εξαίρεση, δεν επιστρέφει undef, σε μη υποστηριζόμενες πλατφόρμες. Σε μηχάνημα που δεν υλοποιεί ούτε την POSIX setpgid(2) ούτε την BSD setpgrp(2), η setpgrp εγείρει εξαίρεση. Αυτή είναι η μοναδική λειτουργία αποτυχίας που δεν περνάει μέσα από την $! - τυλίξτε σε eval αν χρειάζεται να υποβαθμιστείτε ομαλά.

  • EPERM σε μετακινήσεις μεταξύ συνεδριών. Ο πυρήνας απορρίπτει προσπάθειες μετακίνησης μιας διεργασίας σε ομάδα διαφορετικής συνεδρίας, ή μετακίνησης μιας διεργασίας που έχει ήδη καλέσει exec. Πιάστε την $! == EPERM και υποχωρήστε σε εφεδρεία αντί να ξαναπροσπαθείτε.

  • Αποστολή σήματος σε ολόκληρη την ομάδα. Όταν δημιουργηθεί μια ομάδα, το kill SIG, -$pgid παραδίδει το SIG σε κάθε διεργασία της ομάδας. Η σύμβαση του αρνητικού pid είναι ιδιότητα της kill, όχι της setpgrp - αλλά είναι ο λόγος που συνήθως καλείτε την setpgrp εξαρχής.

  • Όχι αρχηγός συνεδρίας. Η setpgrp αλλάζει ομάδα διεργασιών, όχι συνεδρία. Για να αποσυνδεθείτε εντελώς από το ελέγχον τερματικό χρειάζεστε POSIX::setsid, που δημιουργεί νέα συνεδρία και νέα ομάδα σε ένα βήμα.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • getpgrp - διαβάστε το τρέχον id ομάδας διεργασιών· ο προφανής συνεργάτης για επαλήθευση ότι μια κλήση setpgrp είχε αποτέλεσμα

  • POSIX::setpgid - ο POSIX-ονομασμένος περιτυλιγμός γύρω από την ίδια κλήση συστήματος, προτιμητέος σε νέο κώδικα επειδή η σειρά και η σημασιολογία των ορισμάτων του είναι μη αμφίσημες σε όλες τις πλατφόρμες

  • POSIX::setsid - δημιουργεί νέα συνεδρία και νέα ομάδα διεργασιών σε μία κλήση· χρησιμοποιήστε αυτό, όχι το setpgrp, για πλήρη αποσύνδεση από τερματικό

  • fork - η κλήση που σχεδόν πάντα προηγείται της setpgrp· ένα παιδί που θέλει τη δική του ομάδα καλεί setpgrp(0, 0) αμέσως μετά την επιστροφή 0 της fork

  • kill - πώς πραγματικά χρησιμοποιείτε μια ομάδα διεργασιών μόλις την έχετε φτιάξει: το kill SIG, -$pgid στέλνει σήμα σε κάθε μέλος