Σύστημα Fork Call στο C

Fork System Call C



η κλήση συστήματος fork () χρησιμοποιείται για τη δημιουργία θυγατρικών διαδικασιών σε ένα πρόγραμμα C. το πιρούνι () χρησιμοποιείται όταν απαιτείται παράλληλη επεξεργασία στην αίτησή σας. Η λειτουργία συστήματος fork () ορίζεται στις επικεφαλίδες sys/types.h και unistd.h Το Σε ένα πρόγραμμα όπου χρησιμοποιείτε πιρούνι, πρέπει επίσης να χρησιμοποιήσετε κλήση συστήματος αναμονής (). wait () η κλήση συστήματος χρησιμοποιείται για να περιμένει στη διαδικασία γονέα για να τελειώσει η θυγατρική διαδικασία. Για να ολοκληρώσετε μια θυγατρική διαδικασία, η κλήση συστήματος exit () χρησιμοποιείται στη θυγατρική διαδικασία. Η συνάρτηση αναμονής () ορίζεται στην κεφαλίδα sys/wait.h και η συνάρτηση exit () ορίζεται στην κεφαλίδα stdlib.h Το

Εικ. 1: Βασική ροή εργασίας πιρουνιού ()

Εικ. 1: Βασική ροή εργασίας πιρουνιού ()







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



fork () Σύνταξη και τιμή επιστροφής:

Η σύνταξη της λειτουργίας συστήματος fork () έχει ως εξής:



πιρούνι pid_t(κενός)?

Η λειτουργία συστήματος fork () δεν δέχεται κανένα όρισμα. Επιστρέφει έναν ακέραιο αριθμό pid_t Το





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

Απλό πιρούνι () Παράδειγμα:

Ένα απλό παράδειγμα πιρούνι () δίνεται παρακάτω:



#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

intκύριος(κενός) {
pid_t pid=πιρούνι()?

αν(pid== 0) {
printf ('Παιδί => PPID: %d PID: %d n',χορταίνω(),χάλια())?
έξοδος (EXIT_SUCCESS)?
}
αλλού αν(pid>> 0) {
printf ('Parent => PID: %d n',χάλια())?
printf («Περιμένω να τελειώσει η διαδικασία του παιδιού. n')?
Περίμενε(ΜΗΔΕΝΙΚΟ)?
printf («Η διαδικασία του παιδιού ολοκληρώθηκε. n')?
}
αλλού {
printf ('Αδυναμία δημιουργίας παιδικής διαδικασίας. n')?
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Εδώ, χρησιμοποίησα το πιρούνι () για να δημιουργήσω μια θυγατρική διαδικασία από την κύρια/γονική διαδικασία. Στη συνέχεια, εκτύπωσα το PID (Αναγνωριστικό διεργασίας) και το PPID (Αναγνωριστικό γονικής διαδικασίας) από τη διαδικασία παιδιού και γονέα. Στη διαδικασία γονικής αναμονής (NULL) χρησιμοποιείται για να περιμένετε να τελειώσει η διαδικασία για το παιδί. Στη θυγατρική διαδικασία, η έξοδος () χρησιμοποιείται για να ολοκληρωθεί η διαδικασία για το παιδί. Όπως μπορείτε να δείτε, το PID της διαδικασίας γονέα είναι το PPID της θυγατρικής διαδικασίας. Έτσι, η διαδικασία του παιδιού 24738 ανήκει στη διαδικασία γονέα 24731 Το

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

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

κενόςchildTask() {
printf ('Γειά σου Κόσμε n')?
}

κενόςparentTask() {
printf ('Κύρια εργασία. n')?
}

intκύριος(κενός) {
pid_t pid=πιρούνι()?

αν(pid== 0) {
childTask()?
έξοδος (EXIT_SUCCESS)?
}
αλλού αν(pid>> 0) {
Περίμενε(ΜΗΔΕΝΙΚΟ)?
parentTask()?
}
αλλού {
printf ('Δεν είναι δυνατή η δημιουργία παιδικής διαδικασίας.')?
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Η έξοδος του παραπάνω προγράμματος:

Εκτέλεση πολλαπλών παιδικών διεργασιών χρησιμοποιώντας πιρούνι () και βρόχο:

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

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

intκύριος(κενός) {
Για(intΕγώ= 1?Εγώ<= 5?Εγώ++) {
pid_t pid=πιρούνι()?

αν(pid== 0) {
printf ('Παιδική διαδικασία => PPID =%d, PID =%d n',χορταίνω(),χάλια())?
έξοδος (0)?
}
αλλού {
printf ('Γονική διαδικασία => PID =%d n',χάλια())?
printf («Περιμένουμε να τελειώσουν οι διαδικασίες του παιδιού ... n')?
Περίμενε(ΜΗΔΕΝΙΚΟ)?
printf («Η διαδικασία του παιδιού ολοκληρώθηκε. n')?
}
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

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

Παράδειγμα πραγματικής ζωής:

Διαφορετικοί σύνθετοι μαθηματικοί υπολογισμοί όπως md5, sha256 κ.λπ. παραγωγή hash απαιτεί μεγάλη επεξεργαστική ισχύ. Αντί να υπολογίζετε τέτοια πράγματα στην ίδια διαδικασία με το κύριο πρόγραμμα, μπορείτε απλώς να υπολογίσετε το hash σε μια θυγατρική διαδικασία και να επιστρέψετε το hash στην κύρια διαδικασία.

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

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

intgetPIN() {
// χρησιμοποιήστε PPID και PID ως σπόρο
srand (χάλια() +χορταίνω())?
intμυστικό= 1000 + σειρά () % 9000?
ΕΠΙΣΤΡΟΦΗμυστικό?
}

intκύριος(κενός) {
intfd[2]?
σωλήνας(fd)?
pid_t pid=πιρούνι()?

αν(pid>> 0) {
Κλείσε(0)?
Κλείσε(fd[1])?
μετά(fd[0])?

intsecretNumber?
μέγεθος_τreadBytes=ανάγνωση(fd[0], &secretNumber, μέγεθος του(secretNumber))?

printf («Αναμονή PIN ... n')?
Περίμενε(ΜΗΔΕΝΙΚΟ)?
printf ('Bytes διαβάστηκε: %ld n',readBytes)?
printf ('PIN: %d n',secretNumber)?
}
αλλού αν(pid== 0) {
Κλείσε(1)?
Κλείσε(fd[0])?
μετά(fd[1])?

intμυστικό=getPIN()?
γράφω(fd[1], &μυστικό, μέγεθος του(μυστικό))?
έξοδος (EXIT_SUCCESS)?
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Όπως μπορείτε να δείτε, κάθε φορά που τρέχω το πρόγραμμα, λαμβάνω έναν διαφορετικό 4ψήφιο κωδικό PIN.

Έτσι, βασικά έτσι χρησιμοποιείτε την κλήση συστήματος fork () στο Linux. Ευχαριστώ που διαβάσατε αυτό το άρθρο.