Fork System Call Linux

Fork System Call Linux



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

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







Όταν το παιδί δημιουργεί διαδικασίες? Τώρα και οι δύο διαδικασίες θα έχουν τον ίδιο Μετρητή Προγράμματος (PC), οπότε και οι δύο αυτές διαδικασίες θα υποδεικνύουν την ίδια επόμενη εντολή. Τα αρχεία που ανοίγονται από τη διαδικασία γονέα θα είναι τα ίδια για τη θυγατρική διαδικασία.



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



  1. Το αναγνωριστικό διεργασίας της θυγατρικής διαδικασίας είναι ένα μοναδικό αναγνωριστικό διεργασίας που διαφέρει από τα αναγνωριστικά όλων των άλλων υφιστάμενων διαδικασιών.
  2. Το αναγνωριστικό διαδικασίας γονέα θα είναι το ίδιο με το αναγνωριστικό διεργασίας του γονέα του παιδιού.

Ιδιότητες της διαδικασίας του παιδιού

Οι παρακάτω είναι μερικές από τις ιδιότητες που έχει μια διαδικασία παιδιού:





  1. Οι μετρητές της CPU και οι χρήσεις πόρων αρχικοποιούνται για μηδενισμό.
  2. Όταν τερματιστεί η διαδικασία γονέα, οι θυγατρικές διεργασίες δεν λαμβάνουν κανένα σήμα επειδή επαναφέρεται το χαρακτηριστικό PR_SET_PDEATHSIG στο prctl ().
  3. Το νήμα που χρησιμοποιείται για να καλέσετε το πιρούνι () δημιουργεί τη θυγατρική διαδικασία. Έτσι, η διεύθυνση της διαδικασίας του παιδιού θα είναι η ίδια με εκείνη του γονέα.
  4. Ο περιγραφέας αρχείων της διαδικασίας γονέα κληρονομείται από τη θυγατρική διαδικασία. Για παράδειγμα, η μετατόπιση του αρχείου ή της κατάστασης σημαιών και τα χαρακτηριστικά εισόδου/εξόδου θα μοιραστούν μεταξύ των περιγραφών αρχείων των θυγατρικών και των γονικών διαδικασιών. Έτσι, ο περιγραφέας αρχείων της γονικής τάξης θα αναφέρεται στον ίδιο περιγραφέα αρχείων της θυγατρικής τάξης.
  5. Οι περιγραφείς ουράς ανοικτού μηνύματος της διαδικασίας γονέα κληρονομούνται από τη θυγατρική διαδικασία. Για παράδειγμα, εάν ένας περιγραφέας αρχείων περιέχει ένα μήνυμα στη διαδικασία γονέα, το ίδιο μήνυμα θα υπάρχει στον αντίστοιχο περιγραφέα αρχείων της θυγατρικής διαδικασίας. Μπορούμε λοιπόν να πούμε ότι οι τιμές σημαίας αυτών των περιγραφών αρχείων είναι ίδιες.
  6. Ομοίως, οι ανοικτές ροές καταλόγου θα κληρονομηθούν από τις θυγατρικές διαδικασίες.
  7. Η προεπιλεγμένη τιμή χαλάρωσης χρονοδιακόπτη της θυγατρικής τάξης είναι ίδια με την τρέχουσα τιμή χαλάρωσης χρονοδιακόπτη της γονικής τάξης.

Ιδιότητες που δεν κληρονομούνται από τη διαδικασία Child

Τα παρακάτω είναι μερικές από τις ιδιότητες που δεν κληρονομούνται από μια θυγατρική διαδικασία:

  1. Κλείδωμα μνήμης
  2. Το σήμα σε εκκρεμότητα μιας παιδικής τάξης είναι κενό.
  3. Διαδικασία κλειδώματος εγγραφής που σχετίζεται (fcntl ())
  4. Ασύγχρονες λειτουργίες εισόδου/εξόδου και περιεχόμενα εισόδου/εξόδου.
  5. Ειδοποιήσεις αλλαγής καταλόγου.
  6. Χρονοδιακόπτες όπως ξυπνητήρι (), setitimer () δεν κληρονομούνται από την θυγατρική τάξη.

πιρούνι () στο C

Δεν υπάρχουν ορίσματα στο fork () και ο τύπος επιστροφής του fork () είναι ακέραιος. Πρέπει να συμπεριλάβετε τα ακόλουθα αρχεία κεφαλίδας όταν χρησιμοποιείται το fork ():



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

Όταν εργάζεστε με πιρούνι (), μπορεί να χρησιμοποιηθεί για τύπο pid_t για τα αναγνωριστικά διεργασιών ως pid_t ορίζεται σε.

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

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

Σύνταξη πιρουνιού ()

Η σύνταξη της κλήσης συστήματος fork () στο Linux, Ubuntu έχει ως εξής:

πιρούνι pid_t (άκυρο);

Στη σύνταξη ο τύπος επιστροφής είναι pid_t Το Όταν δημιουργηθεί επιτυχώς η θυγατρική διαδικασία, το PID της θυγατρικής διαδικασίας επιστρέφεται στη διαδικασία γονέα και το 0 θα επιστρέψει στην ίδια τη θυγατρική διαδικασία.

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

No arguments are passed to fork(). 

Παράδειγμα 1: Calling fork ()

Εξετάστε το ακόλουθο παράδειγμα στο οποίο χρησιμοποιήσαμε την κλήση συστήματος fork () για να δημιουργήσουμε μια νέα θυγατρική διαδικασία:

ΚΩΔΙΚΑΣ:

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

intκύριος()
{
πιρούνι()?
printf ('Χρήση πιρουνιού () κλήσης συστήματος n')?
ΕΠΙΣΤΡΟΦΗ 0?
}

ΠΑΡΑΓΩΓΗ:

Χρήση κλήσης συστήματος fork ()
Χρήση κλήσης συστήματος fork ()

Σε αυτό το πρόγραμμα, έχουμε χρησιμοποιήσει το πιρούνι (), αυτό θα δημιουργήσει μια νέα θυγατρική διαδικασία. Όταν δημιουργηθεί η θυγατρική διαδικασία, τόσο η διαδικασία γονέα όσο και η θυγατρική διαδικασία θα υποδείξουν την επόμενη εντολή (ίδιος Μετρητής προγράμματος). Με αυτόν τον τρόπο οι υπόλοιπες οδηγίες ή εντολές C θα εκτελεστούν στο συνολικό αριθμό των χρόνων διεργασίας, δηλαδή 2νφορές, όπου n είναι ο αριθμός των κλήσεων συστήματος ().

Έτσι, όταν η κλήση πιρούνι () χρησιμοποιείται μία φορά όπως παραπάνω (21= 2) θα έχουμε την έξοδο μας 2 φορές.

Εδώ όταν χρησιμοποιείται η κλήση συστήματος fork (), η εσωτερική δομή θα μοιάζει με:

Εξετάστε την ακόλουθη περίπτωση στην οποία το πιρούνι () χρησιμοποιείται 4 φορές:

ΚΩΔΙΚΑΣ:

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

intκύριος()
{
πιρούνι()?
πιρούνι()?
πιρούνι()?
πιρούνι()?
printf ('Χρήση κλήσης συστήματος fork ()')?
ΕΠΙΣΤΡΟΦΗ 0?
}

Παραγωγή:

Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call 

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

Παράδειγμα 2: Ο έλεγχος αν το πιρούνι () ήταν επιτυχές

Στο ακόλουθο παράδειγμα χρησιμοποιήσαμε το κατασκεύασμα λήψης αποφάσεων για να δοκιμάσουμε την τιμή (int) που επιστρέφεται με πιρούνι (). Και εμφανίζονται τα αντίστοιχα μηνύματα:

ΚΩΔΙΚΑΣ:

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

intκύριος()
{
pid_t ρ?
Π=πιρούνι()?
αν(Π== -1)
{
printf ('Υπάρχει σφάλμα κατά την κλήση του πιρουνιού ()')?
}
αν(Π==0)
{
printf («Είμαστε στη διαδικασία του παιδιού»)?
}
αλλού
{
printf («Είμαστε στη διαδικασία του γονέα»)?
}
ΕΠΙΣΤΡΟΦΗ 0?
}

ΠΑΡΑΓΩΓΗ:

Είμαστε στη διαδικασία των γονέων
Είμαστε στη διαδικασία του παιδιού

Στο παραπάνω παράδειγμα χρησιμοποιήσαμε τον τύπο pid_t που θα αποθηκεύσει την επιστρεφόμενη τιμή του πιρουνιού (). το πιρούνι () καλείται on line:

Π=πιρούνι()?

Έτσι, η ακέραιη τιμή που επιστρέφεται με το πιρούνι () αποθηκεύεται στο p και στη συνέχεια το p συγκρίνεται για να ελέγξουμε εάν η κλήση του fork () ήταν επιτυχής.

Όταν χρησιμοποιηθεί η κλήση fork () και το παιδί δημιουργηθεί με επιτυχία, η διαδικασία id του παιδιού θα επιστρέψει στη διαδικασία γονέα και το 0 θα επιστρέψει στη θυγατρική διαδικασία. Το αναγνωριστικό της διαδικασίας παιδιού στη διαδικασία Γονέα δεν θα είναι το ίδιο με το Αναγνωριστικό της διαδικασίας παιδιού στην ίδια τη διαδικασία παιδιού. Κατά τη διαδικασία για παιδιά, το αναγνωριστικό της διαδικασίας για παιδιά θα είναι 0.

Με αυτό το σεμινάριο μπορείτε να δείτε πώς να ξεκινήσετε με την κλήση συστήματος fork στο linux.