Κοινή χρήση τεχνολογίας

Διακομιστής αντιδραστήρα υψηλής ταυτόχρονης λειτουργίας [μέσο]

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Διακομιστής αντιδραστήρα υψηλής ταυτόχρονης λειτουργίας [μέσο]

4. Έλεγχος διεργασιών και συγχρονισμός διεργασιών

1. Σήμα

1.1 Βασικές έννοιες των σημάτων

Το σήμα (σήμα) είναι μια διακοπή λογισμικού Είναι μια μέθοδος μετάδοσης μηνυμάτων μεταξύ διεργασιών.

Υπάρχουν πολλοί λόγοι για τους οποίους δημιουργούνται σήματα στο ShellkillκαιkillallΕντολή για αποστολή σήματος:

kill -信号的类型 进程编号
killall -信号的类型 进程名
  • 1
  • 2

1.2 Τύποι σημάτων

όνομα σήματοςτιμή σήματοςΠροεπιλεγμένη ενέργεια επεξεργασίαςΛόγος σηματοδότησης
ΣΙΓΧΟΥΠ1ΕΝΑΤο τερματικό κολλάει ή η διαδικασία ελέγχου τερματίζεται
SIGINT2ΕΝΑΔιακοπή πληκτρολογίου Ctrl+c
SIGQUIT3ντοΤο πλήκτρο διαφυγής του πληκτρολογίου πατιέται
ΣΙΓΙΛ4ντοΠαράνομη οδηγία
SIGTRAP5ντοοδηγίες για το σημείο διακοπής
SIGABRT6ντοΣήμα ματαίωσης που εκδόθηκε από abort(3)
SIGBUS7ντοσφάλμα λεωφορείου
ΣΙΓΦΠΕ8ντοεξαίρεση κινητής υποδιαστολής
ΣΙΓΚΙΛ9ΕΝΑΤο kill -9 σκοτώνει τη διαδικασία, αυτό το σήμα δεν μπορεί να ληφθεί και να αγνοηθεί
SIGUSR110ΕΝΑΣήμα καθορισμένο από το χρήστη 1
SIGSEGV11ντοΜη έγκυρη αναφορά μνήμης (πίνακας εκτός ορίων, λειτουργία μηδενικού δείκτη)
SIGUSR212ΕΝΑΣήμα καθορισμένο από το χρήστη 2
SIGPIPE13ΕΝΑΕγγραφή δεδομένων σε σωλήνα χωρίς διαδικασία ανάγνωσης
SIGALRM14ΕΝΑΣήμα ξυπνητηριού, σήμα που αποστέλλεται από τη λειτουργία alarm().
SIGTERM15ΕΝΑΣήμα τερματισμού, το σήμα που αποστέλλεται από προεπιλογή
SIGSTKFLT16ΕΝΑσφάλμα στοίβας
SIGCHLD17σιΕκπέμπεται όταν τελειώνει η θυγατρική διαδικασία
SIGCONT18ρεΣυνέχιση μιας διακοπείσας διαδικασίας
SIGSTOP19ρεΔιακοπή διαδικασίας
SIGTSTP20ρεΤο τερματικό πατήστε το πλήκτρο διακοπής
SIGTTIN21ρεΗ διαδικασία παρασκηνίου ζητά την ανάγνωση του τερματικού
ΣΙΓΤΤΟΥ22ρεΗ διαδικασία παρασκηνίου ζητά εγγραφή στο τερματικό
SIGURG23σιΑνίχνευση κατάστασης έκτακτης ανάγκης (πρίζες)
SIGXCPU24ντοΥπέρβαση του χρονικού ορίου CPU
SIGXFSZ25ντοΥπέρβαση του ορίου μεγέθους αρχείου
SIGVTALRM26ΕΝΑεικονικό σήμα ρολογιού
ΣΙΓΠΡΟΦ27ΕΝΑΑναλύστε τα σήματα ρολογιού
SIGWINCH28σιΤο μέγεθος του παραθύρου αλλάζει
SIGPOLL29σιΔημοσκόπηση (Sys V)
SIGPWR30ΕΝΑδιακοπή ρεύματος
ΣΙΓΣΥΣ31ντοΠαράνομη κλήση συστήματος

Η προεπιλεγμένη ενέργεια του Α είναι να τερματίσει τη διαδικασία.

Η προεπιλεγμένη ενέργεια του B είναι να αγνοήσει αυτό το σήμα.

Η προεπιλεγμένη ενέργεια του C είναι να τερματίσει τη διαδικασία και να κάνει μια ένδειξη απόθεσης εικόνας πυρήνα.

Η προεπιλεγμένη ενέργεια του D είναι να σταματήσει τη διαδικασία και το πρόγραμμα που εισέρχεται στην κατάσταση διακοπής μπορεί να συνεχίσει να εκτελείται.

1.3 Επεξεργασία σήματος

Υπάρχουν τρεις τρόποι για να χειριστούν οι διεργασίες τα σήματα:

  1. Η προεπιλεγμένη λειτουργία του συστήματος χρησιμοποιείται για τον χειρισμό αυτού του σήματος Η προεπιλεγμένη λειτουργία των περισσότερων σημάτων είναι ο τερματισμός της διαδικασίας.
  2. Ρυθμίστε τη λειτουργία επεξεργασίας διακοπής Μετά τη λήψη του σήματος, η λειτουργία θα το χειριστεί.
  3. Αγνοήστε ένα σήμα και μην κάνετε τίποτα με το σήμα σαν να μην συνέβη ποτέ.

signal()Οι συναρτήσεις μπορούν να ρυθμίσουν τον τρόπο με τον οποίο το πρόγραμμα χειρίζεται τα σήματα.

Δήλωση λειτουργίας:

#include <signal.h>

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
  • 1
  • 2
  • 3
  • 4

Περιγραφή παραμέτρου:

  • sig: Καθορίστε το σήμα προς λήψη.
  • func : Λειτουργία επεξεργασίας σήματος δείκτης. Η συνάρτηση επεξεργασίας πρέπει να λάβει μια ακέραια παράμετρο, η οποία είναι ο αριθμός σήματος που έχει ληφθεί.
  1. SIG_DFL Η μακροεντολή :SIG_DFL αντιπροσωπεύει την προεπιλεγμένη μέθοδο επεξεργασίας σήματος.χρήσηSIG_DFLόπως καιsignalΗ δεύτερη παράμετρος της συνάρτησης υποδεικνύει ότι χρησιμοποιείται η προεπιλεγμένη μέθοδος επεξεργασίας του συστήματος για το σήμα.
  2. SIG_IGN Η μακροεντολή :SIG_IGN σημαίνει να αγνοήσετε το σήμα.χρήσηSIG_IGNόπως καιsignal Η δεύτερη παράμετρος της συνάρτησης υποδεικνύει ότι όταν η διεργασία λάβει το σήμα, θα το αγνοήσει και δεν θα εκτελέσει καμία επεξεργασία. Αυτό μπορεί να αποτρέψει τον απροσδόκητο τερματισμό ή τη διακοπή των διαδικασιών σε ορισμένες περιπτώσεις.
  3. SIG_ERR:SIG_ERR Οι μακροεντολές χρησιμοποιούνται για την ένδειξη σφαλμάτων.δεν είναι όπωςsignalΗ δεύτερη παράμετρος της συνάρτησης χρησιμοποιείται αντί ωςsignal Η τιμή επιστροφής της συνάρτησης υποδεικνύει ότι η κλήση απέτυχε.ανsignalΕάν η κλήση προς τη συνάρτηση αποτύχει, θα επιστρέψειSIG_ERR .Αυτό χρησιμοποιείται συνήθως για την ανίχνευση και την επεξεργασίαsignalΣφάλμα στην κλήση συνάρτησης.

εικόνα-20240709113614147

εικόνα-20240709113230874

εικόνα-20240709113240944

1.4 Ποια είναι η χρήση των σημάτων;

Το πρόγραμμα σέρβις εκτελείται στο παρασκήνιο, αν θέλετε να το σταματήσετε, δεν είναι καλή ιδέα να το σκοτώσετε, γιατί όταν η διαδικασία σκοτώνεται, πεθαίνει ξαφνικά και δεν κανονίζεται μεταγενέστερη εργασία.

Εάν στείλετε ένα σήμα στο πρόγραμμα σέρβις, μετά τη λήψη του σήματος, το πρόγραμμα σέρβις καλεί μια συνάρτηση και γράφει τον μεταγενέστερο κωδικό στη συνάρτηση και το πρόγραμμα μπορεί να εξέλθει με προγραμματισμένο τρόπο.

Η αποστολή σήματος 0 στο πρόγραμμα σέρβις μπορεί να ανιχνεύσει εάν το πρόγραμμα είναι ζωντανό.

εικόνα-20240709135336848

1.5 Αποστολή σημάτων

Το λειτουργικό σύστημα Linux παρέχει kill καιkillall Η εντολή στέλνει ένα σήμα στο πρόγραμμα Στο πρόγραμμα, μπορείτε να χρησιμοποιήσετεkill() Οι λειτουργίες της βιβλιοθήκης στέλνουν σήματα σε άλλες διεργασίες.

Δήλωση λειτουργίας:

int kill(pid_t pid, int sig);
  • 1

kill() Η συνάρτηση παίρνει τις παραμέτρουςsig Το καθορισμένο σήμα μεταβιβάζεται στην παράμετροpid καθορισμένη διαδικασία.

παράμετρος pid Υπάρχουν διάφορες καταστάσεις:

  1. pid > 0 Περάστε το σήμα στη διαδικασία ωςpid επεξεργάζομαι, διαδικασία.
  2. pid = 0 Περάστε το σήμα σε όλες τις διεργασίες στην ίδια ομάδα διεργασιών με την τρέχουσα διεργασία Χρησιμοποιείται συχνά από τη γονική διεργασία για την αποστολή σημάτων στη θυγατρική διαδικασία.
  3. pid < -1 Περάστε το σήμα στο αναγνωριστικό της ομάδας διεργασιών του|pid| όλων των διαδικασιών.
  4. pid = -1 Διαβιβάζει το σήμα σε όλες τις διεργασίες που έχουν άδεια αποστολής του σήματος, αλλά όχι στη διεργασία που έστειλε το σήμα.

2. Τερματισμός διαδικασίας

Υπάρχουν 8 τρόποι για να τερματίσετε μια διαδικασία, 5 από τους οποίους είναι κανονικοί τερματισμοί, αυτοί είναι:

  1. υπάρχει main() Για λειτουργίεςreturn ΕΠΙΣΤΡΟΦΗ;
  2. Καλείται σε οποιαδήποτε λειτουργία exit() λειτουργία;
  3. Καλείται σε οποιαδήποτε λειτουργία _exit() ή_Exit() λειτουργία;
  4. Το τελευταίο νήμα ξεκινά από τη ρουτίνα εκκίνησης του (κύρια λειτουργία νήματος) με return ΕΠΙΣΤΡΟΦΗ;
  5. Κλήθηκε στο τελευταίο νήμα pthread_exit() ΕΠΙΣΤΡΟΦΗ;

Υπάρχουν τρεις τρόποι για να τερματίσετε ασυνήθιστα, είναι:

  1. ΜΕΤΑΦΟΡΑ abort() λειτουργία ακύρωση?
  2. Λαμβάνεται ένα σήμα.
  3. Το τελευταίο νήμα απαντά στο αίτημα ακύρωσης.

2.1 Κατάσταση τερματισμού διαδικασίας

υπάρχει main() Στη συνάρτηση,return Η επιστρεφόμενη τιμή είναι η κατάσταση τερματισμού, εάν όχιreturn δήλωση ή κλήσηexit(), τότε η κατάσταση τερματισμού της διαδικασίας είναι 0.

Στο κέλυφος, προβάλετε την κατάσταση τερματισμού της διαδικασίας:

echo $?
  • 1

3 λειτουργίες για τον κανονικό τερματισμό της διαδικασίας (exit() και_Exit() καθορίζεται από το ISO C,_exit() καθορίζεται από το POSIX):

void exit(int status);
void _exit(int status);
void _Exit(int status);
  • 1
  • 2
  • 3

status Η κατάσταση τερματισμού της διαδικασίας.

εικόνα-20240709143530327

εικόνα-20240709143615950

2.2 Ζήτημα απελευθέρωσης πόρων

  • return Υποδεικνύει ότι όταν επιστρέψει η συνάρτηση, θα κληθεί ο καταστροφέας του τοπικού αντικειμένου.main() σε λειτουργίαreturn Ο καταστροφέας του παγκόσμιου αντικειμένου ονομάζεται επίσης.
  • exit() Υποδεικνύει για τον τερματισμό της διαδικασίας, δεν θα κληθεί ο καταστροφέας του τοπικού αντικειμένου, θα κληθεί μόνο ο καταστροφέας του καθολικού αντικειμένου.
  • _exit() και_Exit() Βγείτε απευθείας και δεν θα πραγματοποιηθούν εργασίες καθαρισμού.

2.3 Λειτουργία τερματισμού της διαδικασίας

Η διαδικασία είναι διαθέσιμη atexit() Η εγγραφή συνάρτησης τερματίζει λειτουργίες (έως 32), αυτές οι λειτουργίες θα είναιexit() Αυτόματη κλήση.

int atexit(void (*function)(void));
  • 1

exit() Η σειρά με την οποία καλούνται οι συναρτήσεις τερματισμού αντιστρέφεται από τη στιγμή της εγγραφής.

εικόνα-20240709143824286

εικόνα-20240709143830549

3. Καλέστε το εκτελέσιμο πρόγραμμα

3.1 λειτουργία system().

system()Η συνάρτηση παρέχει μια απλή μέθοδο εκτέλεσης του προγράμματος, περνώντας το πρόγραμμα και τις παραμέτρους που πρέπει να εκτελεστούν ως συμβολοσειρά.system()Απλά λειτουργία.

Δήλωση λειτουργίας:

int system(const char * string);
  • 1

system()Η τιμή επιστροφής της συνάρτησης είναι πιο ενοχλητική.

  1. Εάν το πρόγραμμα που εκτελείται δεν υπάρχει,system()Η συνάρτηση επιστρέφει μη μηδενική.
  2. Εάν η εκτέλεση του προγράμματος είναι επιτυχής και η κατάσταση εκτέλεσης του εκτελεσμένου προγράμματος είναι 0,system()Η συνάρτηση επιστρέφει 0.
  3. Εάν η εκτέλεση του προγράμματος είναι επιτυχής και η κατάσταση τερματισμού του εκτελεσθέντος προγράμματος δεν είναι 0,system()Η συνάρτηση επιστρέφει μη μηδενική.

3.2 οικογένεια συναρτήσεων exec

execΟι οικογένειες συναρτήσεων παρέχουν έναν άλλο τρόπο κλήσης προγραμμάτων (δυαδικά ή σενάρια φλοιού) μέσα σε μια διαδικασία.

execΗ οικογένεια συναρτήσεων δηλώνεται ως εξής:

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Ειδοποίηση

  1. Εάν η εκτέλεση του προγράμματος αποτύχει, το -1 επιστρέφεται απευθείας και ο λόγος της αποτυχίας αποθηκεύεται στοerrnoΜέσης.
  2. Ο αριθμός διεργασίας της νέας διεργασίας είναι ίδιος με αυτόν της αρχικής διεργασίας, αλλά η νέα διαδικασία αντικαθιστά το τμήμα κώδικα, το τμήμα δεδομένων και τη στοίβα της αρχικής διεργασίας.
  3. Εάν η εκτέλεση είναι επιτυχής, η συνάρτηση δεν θα επιστρέψει όταν καλείται επιτυχώς στο κύριο πρόγραμμαexecΜετά από αυτό, το καλούμενο πρόγραμμα θα αντικαταστήσει το πρόγραμμα κλήσης, δηλαδήexecΔεν θα εκτελεστεί κανένας κωδικός μετά τη λειτουργία.
  4. Στην πραγματική ανάπτυξη, το πιο συχνά χρησιμοποιούμενο είναιexecl()καιexecv(), άλλα χρησιμοποιούνται σπάνια.

4. Δημιουργήστε μια διαδικασία

4.1 Το Linux επεξεργάζεται τα 0, 1 και 2

Όλες οι διεργασίες σε ολόκληρο το σύστημα Linux είναι σε δομή δέντρου.

  • **Διαδικασία Νο. 0 (διαδικασία συστήματος)** είναι ο πρόγονος όλων των διεργασιών Δημιούργησε τις διεργασίες Νο. 1 και Νο. 2.
  • **Η διεργασία Νο. 1 (σύστημα)** είναι υπεύθυνη για την εκτέλεση της προετοιμασίας του πυρήνα και της διαμόρφωσης του συστήματος.
  • **Η διεργασία Νο. 2 (kthreadd)** είναι υπεύθυνη για τον προγραμματισμό και τη διαχείριση όλων των νημάτων του πυρήνα.

χρήσηpstreeΜπορείτε να δείτε το δέντρο διεργασιών με την εντολή:

pstree -p 进程编号
  • 1

4.2 Αναγνώριση διαδικασίας

Κάθε διεργασία έχει ένα μοναδικό αναγνωριστικό διεργασίας που αντιπροσωπεύεται από έναν μη αρνητικό ακέραιο. Αν και μοναδικά, τα αναγνωριστικά διεργασίας μπορούν να επαναχρησιμοποιηθούν. Όταν μια διεργασία τερματίζεται, το αναγνωριστικό διεργασίας της γίνεται υποψήφιο για επαναχρησιμοποίηση. Το Linux χρησιμοποιεί έναν αλγόριθμο καθυστερημένης επαναχρησιμοποίησης, έτσι ώστε το αναγνωριστικό μιας διαδικασίας που δημιουργήθηκε πρόσφατα να διαφέρει από το αναγνωριστικό που χρησιμοποιήθηκε από την πρόσφατα τερματισμένη διαδικασία. Αυτό αποτρέπει το να μπερδευτούν οι νέες διεργασίες ως τερματισμένες διεργασίες που χρησιμοποιούν το ίδιο αναγνωριστικό.

Λειτουργία για λήψη αναγνωριστικού διαδικασίας:

pid_t getpid(void);    // 获取当前进程的ID。
pid_t getppid(void);   // 获取父进程的ID。
  • 1
  • 2

Λειτουργία 4.3 fork().

Μια υπάρχουσα διαδικασία μπορεί να καλέσειfork()Η συνάρτηση δημιουργεί μια νέα διαδικασία.

Δήλωση λειτουργίας:

pid_t fork(void);
  • 1

Εξαρτάται απόfork()Η νέα διαδικασία που δημιουργείται ονομάζεται θυγατρική διαδικασία.

fork() Η συνάρτηση καλείται μία φορά αλλά επιστρέφει δύο φορές. Η διαφορά μεταξύ των δύο επιστροφών είναι ότι η τιμή επιστροφής της θυγατρικής διεργασίας είναι 0, ενώ η τιμή επιστροφής της γονικής διαδικασίας είναι το αναγνωριστικό διεργασίας της νεοδημιουργηθείσας θυγατρικής διεργασίας.

Η θυγατρική διαδικασία και η γονική διαδικασία συνεχίζουν να εκτελούνταιfork()Ο κωδικός μετά από αυτό, Η θυγατρική διαδικασία είναι αντίγραφο της γονικής διαδικασίας. Η θυγατρική διαδικασία έχει ένα αντίγραφο του χώρου δεδομένων της γονικής διεργασίας, του σωρού και της στοίβας (σημείωση: η θυγατρική διεργασία έχει ένα αντίγραφο, δεν είναι κοινόχρηστο με τη γονική διαδικασία).

fork()Μετά από αυτό, η σειρά εκτέλεσης των γονικών και θυγατρικών διεργασιών δεν είναι καθορισμένη.

εικόνα-20240709221535371

εικόνα-20240709221546617

4.4 Δύο χρήσεις του fork()

  1. Η γονική διαδικασία θέλει να αντιγραφεί η ίδια και, στη συνέχεια, η γονική και η θυγατρική διεργασία εκτελούν διαφορετικό κώδικα.Αυτή η χρήση είναι πολύ συνηθισμένη σε προγράμματα υπηρεσιών δικτύου. Η γονική διαδικασία αναμένει την αίτηση σύνδεσης του πελάτηfork(), αφήστε τη θυγατρική διαδικασία να χειριστεί αυτά τα αιτήματα, ενώ η γονική διαδικασία συνεχίζει να περιμένει για το επόμενο αίτημα σύνδεσης.
  2. Η διαδικασία θέλει να εκτελέσει ένα άλλο πρόγραμμα.Αυτή η χρήση είναι πολύ συνηθισμένη στα κοχύλια, από την οποία ξεκινά η διαδικασία του παιδιούfork()Κάλεσαν αμέσως μετά την επιστροφήexec

4.5 Κοινόχρηστα αρχεία

fork()Ένα χαρακτηριστικό είναι ότι οι περιγραφείς αρχείων που ανοίγουν στη γονική διαδικασία θα αντιγραφούν στη θυγατρική διαδικασία και η γονική διαδικασία και η θυγατρική διαδικασία μοιράζονται την ίδια μετατόπιση αρχείου.

Εάν μια γονική διεργασία και μια θυγατρική διεργασία γράψουν σε ένα αρχείο που υποδεικνύεται από τον ίδιο περιγραφέα χωρίς καμία μορφή συγχρονισμού, η έξοδος τους μπορεί να αναμιχθεί μεταξύ τους.

εικόνα-20240709222929369

εικόνα-20240709222803641

Σε αυτό το σημείο μπορείτε να δείτε ότι υπάρχουν μόνο 100.000 σειρές δεδομένων.

εικόνα-20240709222853769

εικόνα-20240709223236254

Αυτή τη στιγμή, θα πρέπει να υπάρχουν 200.000 σειρές δεδομένων, επειδή η λειτουργία εγγραφής αρχείου δεν είναι ατομική, δύο διεργασίες μπορεί να προσπαθήσουν να γράψουν διαφορετικά μέρη του αρχείου προκαλώντας την αποτυχία της εγγραφής Τα δεδομένα παρεμβάλλονται μεταξύ τους.

4.6 συνάρτηση vfork().

vfork()Οι κλήσεις συναρτήσεων και οι τιμές επιστροφής είναι ίδιες μεfork()Το ίδιο, αλλά η σημασιολογία τους είναι διαφορετική.

vfork()Η συνάρτηση χρησιμοποιείται για τη δημιουργία μιας νέας διεργασίας σκοπός της οποίας είναιexecΈνα νέο πρόγραμμα που δεν αντιγράφει το χώρο διευθύνσεων της γονικής διαδικασίας επειδή καλεί αμέσως η θυγατρική διαδικασίαexec , επομένως ο χώρος διευθύνσεων της γονικής διαδικασίας δεν θα χρησιμοποιηθεί. Εάν η θυγατρική διαδικασία χρησιμοποιεί τον χώρο διευθύνσεων της γονικής διαδικασίας, ενδέχεται να προκύψουν άγνωστα αποτελέσματα.

vfork()καιfork()Μια άλλη διαφορά είναι:vfork()Βεβαιωθείτε ότι η θυγατρική διεργασία εκτελείται πρώτα και καλέστε την στη θυγατρική διεργασίαexecήexitΣτη συνέχεια, η γονική διαδικασία συνεχίζει να λειτουργεί.

5. Διαδικασία ζόμπι

Στο λειτουργικό σύστημα, μια διεργασία ζόμπι αναφέρεται σε μια θυγατρική διαδικασία που έχει τερματιστεί αλλά η γονική της διαδικασία δεν έχει ακόμη διαβάσει την κατάσταση εξόδου της. Παρόλο που η διαδικασία ζόμπι δεν εκτελείται πλέον, εξακολουθεί να καταλαμβάνει μια καταχώρηση στον πίνακα διεργασιών, έτσι ώστε ο πυρήνας να μπορεί να αποθηκεύσει τις πληροφορίες κατάστασης εξόδου της διεργασίας (όπως αναγνωριστικό διεργασίας, κατάσταση εξόδου κ.λπ.) έως ότου η γονική διαδικασία διαβάσει αυτές τις πληροφορίες.

5.1 Αιτίες διεργασιών ζόμπι

Εάν η γονική διαδικασία τερματιστεί πριν από τη θυγατρική, η θυγατρική διαδικασία θα φιλοξενηθεί από τη διαδικασία 1 (αυτός είναι επίσης ένας τρόπος για να αφήσετε τη διαδικασία να εκτελεστεί στο παρασκήνιο).

Εάν η θυγατρική διαδικασία τερματιστεί πριν από τη γονική διαδικασία και η γονική διαδικασία δεν επεξεργάζεται τις πληροφορίες εξόδου της θυγατρικής διαδικασίας, τότε η θυγατρική διαδικασία θα γίνει διαδικασία ζόμπι.

5.2 Η βλάβη των διαδικασιών ζόμπι

Ο πυρήνας διατηρεί μια δομή δεδομένων για κάθε θυγατρική διεργασία, συμπεριλαμβανομένου του αριθμού διεργασίας, της κατάστασης τερματισμού, του χρόνου CPU που χρησιμοποιείται κ.λπ. Εάν η γονική διαδικασία επεξεργάζεται τις πληροφορίες εξόδου της θυγατρικής διεργασίας, ο πυρήνας θα απελευθερώσει αυτήν τη δομή δεδομένων. Εάν η γονική διαδικασία δεν επεξεργάζεται τις πληροφορίες εξόδου της θυγατρικής διεργασίας, ο πυρήνας δεν θα απελευθερώσει αυτήν τη δομή δεδομένων και ο αριθμός διεργασίας της θυγατρικής διαδικασίας θα είναι πάντα κατειλημμένος. Οι διαθέσιμοι αριθμοί διεργασιών στο σύστημα είναι περιορισμένοι.

5.3 Μέθοδοι αποφυγής διαδικασιών ζόμπι

  1. Χειρισμός του σήματος SIGCHLD : Όταν η θυγατρική διεργασία τερματιστεί, ο πυρήνας θα στείλει το σήμα SIGCHLD στη γονική διεργασία.Εάν η γονική διαδικασία χρησιμοποιείsignal(SIGCHLD, SIG_IGN)Ειδοποιήστε τον πυρήνα ότι δεν ενδιαφέρεται για την έξοδο από τη θυγατρική διαδικασία και η δομή δεδομένων του θα κυκλοφορήσει αμέσως μετά την έξοδο της θυγατρικής διαδικασίας.
  2. χρήσηwait()/waitpid()λειτουργία: Η γονική διαδικασία περιμένει να τελειώσει η θυγατρική διαδικασία καλώντας αυτές τις συναρτήσεις και αποκτά την κατάσταση εξόδου της, απελευθερώνοντας έτσι τους πόρους που καταλαμβάνει η θυγατρική διαδικασία.
pid_t wait(int *stat_loc); 
pid_t waitpid(pid_t pid, int *stat_loc, int options); 
pid_t wait3(int *status, int options, struct rusage *rusage); 
pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
  • 1
  • 2
  • 3
  • 4

Η τιμή επιστροφής είναι ο αριθμός της θυγατρικής διαδικασίας.

stat_loc Είναι οι πληροφορίες σχετικά με τον τερματισμό της διαδικασίας παιδιού:

α) Εάν τερματιστεί κανονικά, η μακροεντολή WIFEXITED(stat_loc) Επιστροφή αλήθεια, μακροεντολήWEXITSTATUS(stat_loc) Η κατάσταση τερματισμού μπορεί να ληφθεί.

β) Εάν τερματίζει ασυνήθιστα, η μακροεντολή WTERMSIG(stat_loc) Λαμβάνει το σήμα για τον τερματισμό της διαδικασίας.

εικόνα-20240709230911352

εικόνα-20240709231034423

εικόνα-20240709231050581

εικόνα-20240709231124375

εικόνα-20240709231140813

Εάν η γονική διαδικασία είναι απασχολημένη, μπορείτε να κάνετε λήψη SIGCHLD Σήμα, καλούμενο στη λειτουργία επεξεργασίας σήματοςwait()/waitpid()

εικόνα-20240709231439475

εικόνα-20240709231422927

6.Πολλαπλές διαδικασίες και σήματα

[Αποστολή σημάτων μεταξύ διεργασιών](##1.5 Αποστολή σημάτων)

Σε ένα πρόγραμμα υπηρεσίας πολλαπλών διεργασιών, εάν η υποδιεργασία λάβει ένα σήμα εξόδου, η υποδιεργασία θα εξέλθει από μόνη της.

Εάν η γονική διεργασία λάβει ένα σήμα εξόδου, θα πρέπει να στείλει σήματα εξόδου σε όλες τις θυγατρικές διεργασίες και στη συνέχεια να εξέλθει από μόνη της.

εικόνα-20240711222919564

εικόνα-20240711222900141

εικόνα-20240711223111481

7. Κοινή μνήμη

Τα πολλαπλά νήματα μοιράζονται τον χώρο διευθύνσεων μιας διεργασίας,Εάν πολλά νήματα χρειάζονται πρόσβαση στην ίδια μνήμη, απλώς χρησιμοποιήστε καθολικές μεταβλητές.

Σε πολλαπλές διεργασίες, ο χώρος διευθύνσεων κάθε διεργασίας είναι ανεξάρτητος και δεν είναι κοινόχρηστος.Εάν πολλές διεργασίες χρειάζονται πρόσβαση στην ίδια μνήμη, δεν μπορούν να χρησιμοποιηθούν καθολικές μεταβλητές, μπορεί να χρησιμοποιηθεί μόνο κοινόχρηστη μνήμη.

Η Κοινόχρηστη Μνήμη επιτρέπει σε πολλαπλές διεργασίες (δεν απαιτείται σχέση αίματος μεταξύ των διεργασιών) να έχουν πρόσβαση στον ίδιο χώρο μνήμης Είναι ο πιο αποτελεσματικός τρόπος κοινής χρήσης και μεταφοράς δεδομένων μεταξύ πολλαπλών διεργασιών. Οι διεργασίες μπορούν να συνδέσουν την κοινόχρηστη μνήμη με τον δικό τους χώρο διευθύνσεων Εάν μια διεργασία τροποποιήσει τα δεδομένα στην κοινόχρηστη μνήμη, τα δεδομένα που διαβάζονται από άλλες διεργασίες θα αλλάξουν επίσης.

Η κοινόχρηστη μνήμη δεν παρέχει μηχανισμό κλειδώματος, δηλαδή όταν μια διεργασία διαβάζει/εγγράφει κοινόχρηστη μνήμη, δεν εμποδίζει άλλες διεργασίες να την διαβάσουν/εγγράψουν.Εάν θέλετε να κλειδώσετε την ανάγνωση/εγγραφή της κοινόχρηστης μνήμης, μπορείτε να χρησιμοποιήσετε έναν σηματοφόρο . Το Linux παρέχει ένα σύνολο λειτουργιών για τη λειτουργία κοινής μνήμης.

7.1 συνάρτηση shmget

Αυτή η λειτουργία χρησιμοποιείται για τη δημιουργία/απόκτηση κοινόχρηστης μνήμης.

 int shmget(key_t key, size_t size, int shmflg);
  • 1
  • κλειδί Η βασική τιμή της κοινόχρηστης μνήμης είναι ένας ακέραιος αριθμός (typedef unsigned int key_t), γενικά σε δεκαεξαδικό, για παράδειγμα 0x5005, τα κλειδιά διαφορετικών κοινών αναμνήσεων δεν μπορούν να είναι ίδια.
  • Μέγεθος Μέγεθος κοινόχρηστης μνήμης, σε byte.
  • shmflg Τα δικαιώματα πρόσβασης για κοινόχρηστη μνήμη είναι τα ίδια με τα δικαιώματα για αρχεία, για παράδειγμα0666|IPC_CREAT Υποδεικνύει ότι εάν η κοινόχρηστη μνήμη δεν υπάρχει, δημιουργήστε την.
  • επιστρεφόμενη τιμή: Επιστρέφει το αναγνωριστικό της κοινόχρηστης μνήμης (ακέραιος αριθμός μεγαλύτερος από 0) σε περίπτωση επιτυχίας, -1 σε περίπτωση αποτυχίας (το σύστημα έχει ανεπαρκή μνήμη και δεν διαθέτει δικαιώματα).

εικόνα-20240711224223200

εικόνα-20240711224212293

χρήση ipcs -m Μπορείτε να δείτε την κοινόχρηστη μνήμη του συστήματος, όπως: κλειδί, αναγνωριστικό κοινόχρηστης μνήμης (shmid), κάτοχος, δικαιώματα (perms) και μέγεθος (byte).

χρήση ipcrm -m 共享内存id Η κοινόχρηστη μνήμη μπορεί να διαγραφεί με μη αυτόματο τρόπο ως εξής:

εικόνα-20240711225202860

Σημείωση: Τα κοντέινερ δεν μπορούν να χρησιμοποιηθούν για τύπους δεδομένων στην κοινόχρηστη μνήμη, μπορούν να χρησιμοποιηθούν μόνο βασικοί τύποι δεδομένων.

7.2 λειτουργία shmat

Αυτή η λειτουργία χρησιμοποιείται για τη σύνδεση της κοινόχρηστης μνήμης στον χώρο διευθύνσεων της τρέχουσας διαδικασίας.

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • 1
  • shmid Εξαρτάται απόshmget() Το αναγνωριστικό κοινόχρηστης μνήμης που επιστρέφεται από τη συνάρτηση.
  • shmaddr Καθορίστε τη θέση διεύθυνσης όπου η κοινόχρηστη μνήμη είναι συνδεδεμένη με την τρέχουσα διαδικασία Συνήθως συμπληρώνετε το 0 για να επιτρέψετε στο σύστημα να επιλέξει τη διεύθυνση της κοινόχρηστης μνήμης.
  • shmflg Bit σημαίας, συνήθως γεμάτο με 0.

Επιστρέφει τη διεύθυνση έναρξης της κοινόχρηστης μνήμης όταν η κλήση είναι επιτυχής και επιστρέφει όταν αποτύχει. (void *)-1

Λειτουργία 7.3 shmdt

Αυτή η λειτουργία χρησιμοποιείται για την αποσύνδεση της κοινόχρηστης μνήμης από την τρέχουσα διαδικασία, η οποία ισοδυναμεί με shmat() Η αντίστροφη λειτουργία μιας συνάρτησης.

int shmdt(const void *shmaddr);
  • 1
  • shmaddr shmat() Η διεύθυνση που επιστρέφεται από τη συνάρτηση.

Επιστρέφει 0 εάν η κλήση επιτύχει και -1 εάν αποτύχει.

Λειτουργία 7,4 shmctl

Αυτή η λειτουργία χρησιμοποιείται για τη λειτουργία κοινής μνήμης Η πιο συχνά χρησιμοποιούμενη λειτουργία είναι η διαγραφή της κοινόχρηστης μνήμης.

int shmctl(int shmid, int command, struct shmid_ds *buf);
  • 1
  • shmid shmget() Το αναγνωριστικό κοινόχρηστης μνήμης που επιστρέφεται από τη συνάρτηση.
  • εντολή Οδηγίες για τη λειτουργία της κοινόχρηστης μνήμης Εάν θέλετε να διαγράψετε την κοινόχρηστη μνήμη, συμπληρώστεIPC_RMID
  • buf Η διεύθυνση της δομής δεδομένων που χειρίζεται την κοινόχρηστη μνήμη Εάν θέλετε να διαγράψετε την κοινόχρηστη μνήμη, συμπληρώστε το 0.

Επιστρέφει 0 εάν η κλήση επιτύχει και -1 εάν αποτύχει.

Σημείωση, χρήση root Η δημιουργημένη κοινόχρηστη μνήμη δεν μπορεί να διαγραφεί από τους απλούς χρήστες ανεξάρτητα από τα δικαιώματα που έχουν δημιουργηθεί.

εικόνα-20240711230653886

εικόνα-20240711230522921

7.5 Κυκλική ουρά

7.6 Κυκλική ουρά με βάση την κοινόχρηστη μνήμη

Επιστρέφει 0 εάν η κλήση επιτύχει και -1 εάν αποτύχει.

Λειτουργία 7,4 shmctl

Αυτή η λειτουργία χρησιμοποιείται για τη λειτουργία κοινής μνήμης Η πιο συχνά χρησιμοποιούμενη λειτουργία είναι η διαγραφή της κοινόχρηστης μνήμης.

int shmctl(int shmid, int command, struct shmid_ds *buf);
  • 1
  • shmid shmget() Το αναγνωριστικό κοινόχρηστης μνήμης που επιστρέφεται από τη συνάρτηση.
  • εντολή Οδηγίες για τη λειτουργία της κοινόχρηστης μνήμης Εάν θέλετε να διαγράψετε την κοινόχρηστη μνήμη, συμπληρώστεIPC_RMID
  • buf Η διεύθυνση της δομής δεδομένων που χειρίζεται την κοινόχρηστη μνήμη Εάν θέλετε να διαγράψετε την κοινόχρηστη μνήμη, συμπληρώστε το 0.

Επιστρέφει 0 εάν η κλήση επιτύχει και -1 εάν αποτύχει.

Σημείωση, χρήση root Η δημιουργημένη κοινόχρηστη μνήμη δεν μπορεί να διαγραφεί από τους απλούς χρήστες ανεξάρτητα από τα δικαιώματα που έχουν δημιουργηθεί.

[Οι εικόνες εξωτερικού συνδέσμου μεταφέρονται...(img-v6qW3XRA-1720711279572)]

[Οι εικόνες εξωτερικού συνδέσμου μεταφέρονται...(img-CG0tGAne-1720711279572)]Η μεταφορά της εικόνας του εξωτερικού συνδέσμου απέτυχε Ο ιστότοπος προέλευσης μπορεί να διαθέτει μηχανισμό κατά της βδέλλας.
Η μεταφορά της εικόνας του εξωτερικού συνδέσμου απέτυχε Ο ιστότοπος προέλευσης μπορεί να διαθέτει μηχανισμό κατά της βδέλλας.
Η μεταφορά της εικόνας του εξωτερικού συνδέσμου απέτυχε Ο ιστότοπος προέλευσης μπορεί να διαθέτει μηχανισμό κατά της βδέλλας.

7.5 Κυκλική ουρά

7.6 Κυκλική ουρά με βάση την κοινόχρηστη μνήμη