Processes.

Slides:



Advertisements
Παρόμοιες παρουσιάσεις
ΧΡΟΝΟΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΔΙΕΡΓΑΣΙΩΝ
Advertisements

ΙΩΑΝΝΗΣ ΚΩΝΣΤΑΝΤΙΝΟΥ 2ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΠΑΡΑΣΚΕΥΗ 26 ΟΚΤΩΒΡΙΟΥ 2012 ΑΙΘΟΥΣΑ Β4 11.
Προγραμματισμός Ι Προτάσεις ελέγχου ροής Ο πιο συνηθισμένος τρόπος εκτέλεσης είναι ο ακολουθιακός: δύο ή περισσότερες προτάσεις βρίσκονται διατεταγμένες.
Νήματα στη Java Καρακασίδης Αλέξανδρος Καστίδου Γεωργία Παπαφώτη Μαρία
POINTERS, AGGREGATION, COMPOSITION. POINTERS TO OBJECTS.
Υλοποίηση μεταφραστή C με επεκτάσεις OpenMP Λεοντιάδης Ηλίας Τζούμας Γεώργιος Πτυχιακή εργασία Τελική παρουσίαση Υπεύθυνος καθηγητής Β. Β. Δημακόπουλος.
1 Κλήση Απομακρυσμένων Διεργασιών (Remote Procedure Call - RPC) Γεωργόπουλος Άλκης Κολωνιάρη Γεωργία Κοντογιώργης Τάσος Λεοντιάδης Ηλίας Πετράκης Γιάννης.
ΜΑΘΗΜΑ 7ο Κυκλικές και Διπλά Συνδεδεμένες Λίστες,
Κεφάλαιο 6 Υλοποίηση Γλωσσών Προγραμματισμού
Κεφάλαιο 6 Threads. 2 Στον παραδοσιακό προγραμματισμό όταν ένα πρόγραμμα εκτελείται ονομάζεται process (διεργασία) και οι εντολές του εκτελούνται σειριακά.
ΛΟΓ102: Τεχνολογία Λογισμικού Ι Διδάσκων: Νίκος Παπασπύρου 1Νίκος ΠαπασπύρουΛΟΓ102:
Message Passing Interface (MPI)
ΤΕΧΝΙΚΕΣ Αντικειμενοστραφουσ προγραμματισμου
ΤΕΧΝΙΚΕΣ Αντικειμενοστραφουσ προγραμματισμου
Τύποι πραγματικών αριθμών
Λειτουργικά Συστήματα
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Πίνακες Κλάσεις και Αντικείμενα.
Συναρτήσεις Κληση/Επιστροφη Παραμετροι
24/11/2003Message Passing Interface (MPI)1 Αθήνα, Νοέμβριος 2003 Συστήματα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστημάτων.
22/11/2004Message Passing Interface (MPI)1 Αθήνα, Νοέμβριος 2004 Συστήματα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστημάτων.
Databases & Qt Μανούσης Πέτρος ΑΜ: 862
ΗΥ-150 Προγραμματισμός Εντολές Ελέγχου Ροής.
Σχεδίαση-Ανάπτυξη Εφαρμογών Πληροφορικής Αντώνιος Συμβώνης, ΕΜΠ, Slide 1 Week 4: Exceptions Εβδομάδα 4: Εξαιρέσεις [Exceptions]
ΙΩΑΝΝΗΣ ΚΩΝΣΤΑΝΤΙΝΟΥ 2ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΠΑΡΑΣΚΕΥΗ 11 ΟΚΤΩΒΡΙΟΥ 2012 ΑΙΘΟΥΣΑ Β4 1.
NIKOΛΑΟΣ ΝΤΙΡΛΗΣ 5ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΑΙΘΟΥΣΑ Β4 1.  Ένα thread έχει: ID, program counter, register set, stack  Μοιράζεται με τα άλλα threads της ίδιας διεργασίας.
ΙΩΑΝΝΗΣ ΚΩΝΣΤΑΝΤΙΝΟΥ 3ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΠΑΡΑΣΚΕΥΗ 19 ΟΚΤΩΒΡΙΟΥ 2012 ΑΙΘΟΥΣΑ Β4 1.
Νήματα Οι διεργασίες έχουν τα παρακάτω συστατικά:
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Στατικές μέθοδοι και μεταβλητές Εσωτερικές κλάσεις.
ΕΠΑΝΑΛΗΨΗΕΠΑΝΑΛΗΨΗ ΠΡΟΓΡΑΜΜΑΤΑ. ΠΡΟΓΡΑΜΜΑ 1 ΕΞΗΓΗΣΤΕ ΤΙ ΕΞΟΔΟ ΠΑΡΑΓΕΙ ΤΟ ΠΑΡΑΚΑΤΩ ΠΡΟΓΡΑΜΜΑ #include int main() { char ch; int i; float fl; printf("dose.
Η ΓΛΩΣΣΑ C ΜΑΘΗΜΑ 2.
Υποθετικός τελεστής Ο υποθετικός τελεστής (?:) αποτελείται από δύο σύμβολα. Ανήκει στην κατηγορία των τελεστών που αποτελούνται από συνδυασμό συμβόλων.
1 Ολυμπιάδα Πληροφορικής Μάθημα 7. 2 Στόχοι μαθήματος Δημιουργία συναρτήσεων από το χρήστη Δομή προγράμματος με συναρτήσεις Συναρτήσεις και παράμετροι.
Πάνω προς Κάτω Σχεδιασμός και Συναρτήσεις
Message Passing Interface (MPI) Συστήματα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστημάτων Αθήνα, Δεκέμβριος 2002.
Κεφάλαιο 10 – Υποπρογράμματα
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Copy Constructor Deep and Shallow Copies.
ΣΤΟΙΧΕΙΑ ΤΗΣ ΓΛΩΣΣΑΣ C++ Πέρασμα παραμέτρων, συναρτήσεις δόμησης και αποδόμησης.
Διεργασίες Λειτουργικά Συστήματα. Λειτουργικά Συστήματα/ Slide 2 Η Έννοια της Διεργασίας * Διεργασία (Process) – ο μηχανισμός εκτέλεσης ενός προγράμματος.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Συναρτήσεις.
Threads Στον παραδοσιακό προγραμματισμό όταν ένα πρόγραμμα εκτελείται ονομάζεται process (διεργασία) και οι εντολές του εκτελούνται σειριακά η μία μετά.
ΗΥ 150 – Προγραμματισμός Ξενοφών Ζαμπούλης ΗΥ -150 Προγραμματισμός Αρχεία.
ΗΥ150 – ΠρογραμματισμόςΞ. Ζαμπούλης ΗΥ-150 Προγραμματισμός Αρχεία.
ΛΟΓ201: Τεχνολογία Λογισμικού ΙΙ Διδάσκων: Νίκος Παπασπύρου 1Νίκος ΠαπασπύρουΛΟΓ201:
Διεργασίες.
ΗΥ150 – Προγραμματισμός Ξενοφών Ζαμπούλης 1 getchar() /* char_count.c A program to count characters of input. */ main() { int c ; int count = 0; while.
ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΕΣ ΤΕΧΝΙΚΕΣ Διδάσκοντες:Γιάννης Μαΐστρος Στάθης Ζάχος Νίκος Παπασπύρου
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Τύποι Μεταβλητών Τελεστές Βασική Είσοδος/Έξοδος.
Νήματα με την χρήση των Posix Threads (pthreads)‏.
Κωνσταντίνος Αντωνής © 2014Διαδικτυακός και Ταυτόχρονος Προγραμματισμός Ζητήματα Σχεδίασης Λογισμικού Πελάτη 1.
Λειτουργικά Συστήματα Ενότητα # 10: Προγραμματισμός UNIX Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής.
ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΕΙΣΑΓΩΓΗ ΣΤΟΥΣ Η/Υ 1 Εισαγωγή στη γλώσσα Προγραμματισμού C ΠΙΝΑΚΕΣ (arrays)
Τεχνολογία και Προγραμματισμός Υπολογιστών
Αντικειμενοστραφής Προγραμματισμός Ι
Κατανεμημένα Συστήματα
Συναρτήσεις.
ΤΕΧΝΙΚΕΣ Αντικειμενοστραφουσ προγραμματισμου
Δείκτες Προγραμματισμός Ι
Περιβάλλον, διαχείριση και ιεραρχίες διεργασιών
Ενισχυτική διδασκαλία
Ενισχυτική διδασκαλία
Λειτουργικά Συστήματα και Ασφάλεια Πληροφοριακών Συστημάτων ΔΙΕΡΓΑΣΙΕΣ
ΕΝΤΟΛΕΣ ΕΠΙΛΟΓΗΣ Η εντολή if if ( παράσταση) εντολή επόμενη εντολή.
for (παράσταση_1; παράσταση_2; παράσταση_3)
Τεχνολογία και Προγραμματισμός Υπολογιστών
Εισαγωγή στα Λειτουργικά Συστήματα (ΛΣ) Operating Systems (OS)
Εισαγωγή στον Προγ/μό Υπολογιστών
Δημιουργία Διεργασιών
ΗΥ-150 Προγραμματισμός Αναδρομή (1/2).
Αρχές Προγραμματισμού (C)
Λήψη Αποφάσεων και Συναρτήσεις Ελέγχου
Μεταγράφημα παρουσίασης:

Processes

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

Εισαγωγή Αρκετά προγράμματα εκτελούνται ως δαίμονες Εκκινούν και εκτελούνται στο background, συνήθως, χωρίς αλληλεπίδραση με τους χρήστες Μπορεί να δημιουργηθεί μια ιεραρχία διεργασιών με τη μορφή πατέρας – παιδί (parent – child) Ο πυρήνας κρατά συγκεκριμένες πληροφορίες για κάθε διεργασία όπως το ID κάθε διεργασίας (process ID – PID)

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

Εισαγωγή

Ιεραρχία Διεργασιών Όταν μια διεργασία δημιουργεί / καλεί μια νέα διεργασία τότε ονομάζεται πατρική διεργασία (parent) ενώ η καλούμενη ονομάζεται διεργασία παιδί (child) Ο πυρήνας του Linux χρησιμοποιεί ένα scheduler διεργασιών ώστε να αποφασίζει το ποια διεργασία θα είναι αυτή που θα χρησιμοποιήσει τον επεξεργαστή Κάθε διεργασία έχει και μια προτεραιότητα που υιοθετείται από τον scheduler ώστε να αποφασίσει τη σειρά εκτέλεσης των διεργασιών Διεργασίες με υψηλή προτεραιότητα εκτελούνται πιο συχνά ενώ διεργασίες με χαμηλή προτεραιότητα εκτελούνται πιο αραιά

Ιεραρχία Διεργασιών Η προκαθορισμένη προτεραιότητα είναι ίση με 0 Το εύρος τιμών των προτεραιοτήτων είναι από -20 μέχρι +20 Το λειτουργικό σύστημα καθορίζει την προτεραιότητα κάθε διεργασίας με βάση μια nice τιμή και την συμπεριφορά της κάθε διεργασίας Για παράδειγμα, διεργασίες που εκτελούνται για μεγάλες χρονικές περιόδους χωρίς διακοπές ‘παίρνουν’ χαμηλές προτεραιότητες

Δημιουργία και Εκτέλεση Διεργασιών Έχουμε τη δυνατότητα μέσα από ένα πρόγραμμα να δημιουργήσουμε μια διεργασία και να την εκτελέσουμε με τη βοήθεια της βιβλιοθήκης stdlib.h της C Για το σκοπό αυτό κάνουμε χρήση της συνάρτησης int system (const char *string);

Δημιουργία και Εκτέλεση Διεργασιών Στο ακόλουθο παράδειγμα, παρουσιάζουμε την εκτέλεση της εντολής ps ax του Linux μέσα από ένα πρόγραμμα C. #include <stdlib.h> #include <stdio.h> int main() { printf("Running ps with system\n"); system("ps ax"); printf("Done.\n"); exit(0); }

Δημιουργία και Εκτέλεση Διεργασιών Μπορούμε να θέσουμε την εκτέλεση της εντολής ps ax στο παρασκήνιο θέτοντας την εντολή system(“ps ax &”); Προγραμματιστικά το PID αναπαριστάται από τον τύπο pid_t που ορίζεται στη βιβλιοθήκη <sys/types.h> Η κλήση συστήματος pid_t getpid (void); μας επιστρέφει το PID της διεργασίας ενώ η pid_t getppid (void); μας δίνει το PID της πατρικής

Δημιουργία και Εκτέλεση Διεργασιών #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { printf ("My pid=%d\n", getpid ( )); printf ("Parent's pid=%d\n", getppid ( )); exit(0); }

Τερματισμός Διεργασιών Ο τερματισμός των διεργασιών γίνεται με την εντολή void exit (int status); και με χρήση της βιβλιοθήκης <stdlib.h> Μια κλήση στην exit() οδηγεί στην εκτέλεση κάποιων απαραίτητων βημάτων και στη συνέχεια στον τερματισμό της διεργασίας Το status & 0377 επιστρέφει στην πατρική διεργασία, η τιμή 0 δείχνει επιτυχία ενώ μια τιμή διαφορετική του 0 δείχνει ανεπιτυχή εκτέλεση Τα EXIT_SUCCESS και EXIT_FAILURE καθορίζονται για να δείξουν επιτυχία ή αποτυχία Συνεπώς, μια επιτυχής έξοδος μπορεί να επιδειχθεί με την ακόλουθη εντολή exit (EXIT_SUCCESS);

Τερματισμός Διεργασιών Τα βήματα που επιτελούνται πριν το τερματισμό μιας διεργασίας είναι τα ακόλουθα: Καλούνται όλες οι συναρτήσεις που έχουν καταχωρηθεί με τις atexit( ), on_exit( ) σε αντίστροφη σειρά καταχώρησης. Επιχειρείται το flushing όλων των ανοιχτών Ι/Ο ροών. Διαγράφονται όλα τα προσωρινά αρχεία που έχουν δημιουργηθεί με τη συνάρτηση tmpfile( ). Η exit() καλεί την _exit() ώστε ο πυρήνας να διαχειριστεί την υπόλοιπη διαδικασία τερματισμού της διεργασίας. #include <unistd.h> void _exit (int status);

Τερματισμός Διεργασιών Η κλήση συστήματος atexit() επιτρέπει τον καθορισμό συναρτήσεων που θα εκτελεστούν κατά την ομαλή διαδικασία τερματισμού μιας διεργασίας, π.χ. με κλήση της exit() ή της return. #include <stdlib.h> int atexit (void (*function)(void));

Τερματισμός Διεργασιών #include <stdio.h> #include <stdlib.h> void out (void) { printf ("atexit( ) succeeded!\n"); } int main (void) if (atexit (out)) fprintf(stderr, "atexit( ) failed!\n"); return 0;

Τερματισμός Διεργασιών Ενώ η atexit() έχει καθοριστεί σύμφωνα με το POSIX 1003.1-2001, το SunOS 4 ορίζει την ισοδύναμη της που είναι η on_exit() H on_exit() έχει την ίδια λειτουργία με την atexit(). #include <stdlib.h> int on_exit (void (*function)(int , void *), void *arg);

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

Οικογένεια exec Οι εντολές exec έχουν ως εξής: #include <unistd.h> char **environ; int execl(const char *path, const char *arg0, ..., (char *)0); int execlp(const char *file, const char *arg0, ..., (char *)0); int execle(const char *path, const char *arg0, ..., (char *)0, char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]);

Οικογένεια exec #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { printf("Running ps with execlp\n"); execlp("ps", "ps", "ax", (char *)0); printf("Done.\n"); exit(0); }

Εντολή fork Όταν επιθυμούμε να χρησιμοποιήσουμε τις διεργασίες ώστε να εκτελούν περισσότερες από μια εργασίες κάθε φορά τότε θα πρέπει είτε να υιοθετήσουμε προγραμματισμό με νήματα (threads) είτε να δημιουργήσουμε μια ξεχωριστή διεργασία για το σκοπό αυτό Για τη δημιουργία ξεχωριστών διεργασιών χρησιμοποιούμε την εντολή fork() Η εντολή ‘διπλασιάζει’ την τρέχουσα διεργασία δημιουργώντας μια νέα εγγραφή στον πίνακα των διεργασιών που διατηρεί το Λειτουργικό Σύστημα Η νέα διεργασία είναι σχεδόν πανομοιότυπη με την αρχική και εκτελεί τον ίδιο κώδικα όμως με το δικό της χώρο δεδομένων, περιβάλλον και περιγραφείς αρχείων

Εντολή fork Η σύνταξη της fork() έχει ως ακολούθως: #include <sys/types.h> #include <unistd.h> pid_t fork(void);

Εντολή fork Το επόμενο σχήμα μας δείχνει τον τρόπο εκτέλεσης της fork().

Εντολή fork Η fork() μας επιτρέπει να αναγνωρίσουμε μέσα στον κώδικα το ποια διεργασία είναι μέσω του αποτελέσματος εκτέλεσης Αν η fork() επιστρέψει -1, τότε κάποιο σφάλμα έχει συμβεί Για παράδειγμα, το σφάλμα εκτέλεσης θα εμφανιστεί αν η πατρική διεργασία ξεπεράσει το μέγιστο αριθμό παιδιών που μπορεί να δημιουργήσει (CHILD_MAX) Αν η fork() επιστρέψει 0, τότε πρόκειται για τη διεργασία παιδί στην πατρική διεργασία επιστρέφει το PID της νέας διεργασίας – παιδί Η νέα διεργασία και η πατρική συνεχίζουν να εκτελούνται όπως η αρχική διεργασία

Εντολή fork Παράδειγμα 1 pid_t new_pid; new_pid = fork(); switch(new_pid) { case -1 : /* Error */ break; case 0 : /* We are child */ default : /* We are parent */ }

Εντολή fork Παράδειγμα 2 pid_t pid; pid = fork ( ); if (pid > 0) printf ("I am the parent of pid=%d!\n", pid); else if (!pid) printf ("I am the baby!\n"); else if (pid == -1) perror ("fork");

Εντολή fork case 0: message = "This is the child"; n = 5; break; #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t pid; char *message; int n; printf("fork program starting\n"); pid = fork(); switch(pid) case -1: perror("fork failed"); exit(1); case 0: message = "This is the child"; n = 5; break; default: message = "This is the parent"; n = 3; } for(; n > 0; n--) { puts(message); sleep(1); exit(0);

Εντολή fork Αποτέλεσμα εκτέλεσης:

Εντολή fork Άλλο ένα παράδειγμα:

Εντολή fork Αποτελέσματα:

Αναμονή Τερματισμού Διεργασιών Η δημιουργία μιας νέας διεργασίας με την εντολή fork() αποδίδει ανεξαρτησία στην εκτέλεση της διεργασίας – παιδί Όμως, ορισμένες φορές, η πατρική διεργασία θα πρέπει να γνωρίζει το πέρας της εκτέλεσης της διεργασίας – παιδί Ιδιαίτερα σε περιπτώσεις όπου η πατρική – διεργασία δημιουργεί πολλαπλές διεργασίες Η εντολή wait επιτρέπει στην πατρική διεργασία να περιμένει το πέρας της εκτέλεσης των διεργασιών – παιδιών #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc);

Αναμονή Τερματισμού Διεργασιών Με την εντολή wait η διεργασία – πατέρας σταματά μέχρι ένα από τις διεργασίες – παιδιά τερματίσει την εκτέλεσή του Η κλήση της εντολής επιστρέφει το PID διεργασίας – παιδί Η πληροφορία της κατάστασης της διεργασίας παιδιού (status information) είναι η τιμή που επιστρέφει η main ή η τιμή που περνάει με την εντολή exit Εφόσον ο δείκτης stat_loc δεν είναι null, στη θέση που δείχνει ο δείκτης θα γραφτεί το status information Στη βιβλιοθήκη sys/wait.h περιλαμβάνεται ένα σύνολο μακρο-εντολών με τις οποίες μπορούμε να μεταφράσουμε το status information

Αναμονή Τερματισμού Διεργασιών

Αναμονή Τερματισμού Διεργασιών Παράδειγμα:

Αναμονή Τερματισμού Διεργασιών Αποτέλεσμα:

Αναμονή Τερματισμού Διεργασιών Όταν μια διεργασία – παιδί τερματίσει τότε η σύνδεση πατέρα – παιδί παραμένει ‘ζωντανή’ μέχρι η διεργασία - πατέρας να τερματίσει ή να καλέσει ξανά την εντολή wait Η διεργασία παιδί παραμένει στον πίνακα των διεργασιών αφού ο κωδικός εξόδου της πρέπει να είναι αποθηκευμένος αφού υπάρχει η πιθανότητα η διεργασία – πατέρας να καλέσει την εντολή wait Σε αυτές τις περιπτώσεις η διεργασία – παιδί ονομάζεται διεργασία zombie

Αναμονή Τερματισμού Διεργασιών Στο ακόλουθο παράδειγμα, η διεργασία – παιδί τερματίζει την εκτύπωση των μηνυμάτων πριν την πατρική διεργασία

Αναμονή Τερματισμού Διεργασιών Αποτέλεσμα:

Αναμονή Τερματισμού Διεργασιών Ένας άλλος τρόπος για να περιμένουμε τον τερματισμό εκτέλεσης μιας διεργασίας – παιδί είναι η εντολή waitpid() #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *stat_loc, int options);

Αναμονή Τερματισμού Διεργασιών Η παράμετρος pid καθορίζει επ’ ακριβώς το ποια διεργασία είναι αυτή της οποίας θα αναμείνουμε τον τερματισμό Οι τιμές που μπορεί να πάρει έχουν ως ακολούθως: < -1. Αναμένει για οποιαδήποτε διεργασία – παιδί για την οποία το ID της ομάδας διεργασιών είναι ίσο με την απόλυτη τιμή της τιμής που δίνουμε. Για παράδειγμα, αν βάλουμε -500 περιμένουμε να τερματιστεί η ομάδα διεργασιών με ID ίσο με 500. -1. Αναμένουμε για τον τερματισμό οποιασδήποτε διεργασίας – παιδί (ίδια με την εντολή wait()). 0. Αναμένουμε για τον τερματισμό οποιασδήποτε διεργασίας – παιδί που ανήκει στην ίδια ομάδα διεργασιών. > 0. Αναμένουμε τον τερματισμό οποιαδήποτε διεργασίας που ανήκει στην ομάδα διεργασιών που έχει ID ίσο με τον αριθμό που δίνουμε.

Ασκήσεις με fork() #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { int x = 1; pid_t pid = fork(); if (pid == 0) { printf("Child has x = %d\n", ++x); } else { printf("Parent has x = %d\n", --x); printf("Bye from process %d with x = %d\n", getpid(), x);

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() printf("L0\n"); fork(); printf("L1\n"); printf("Bye\n");

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() #include <stdio.h> #include  <sys/types.h> int main() {     fork();     printf("hello\n");     return 0; }

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() void fork3() { printf("L0\n"); fork(); printf("L1\n"); printf("L2\n"); printf("Bye\n"); }

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() void fork4() { printf("L0\n"); if (fork() != 0) { printf("L1\n"); printf("L2\n"); fork(); } printf("Bye\n");

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() void fork6() { if (fork() == 0) { /* Child */ printf("Terminating Child, PID = %d\n", getpid()); exit(0); } else { printf("Running Parent, PID = %d\n", getpid()); while (1) ; /* Infinite loop */ }

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() void fork7() { if (fork() == 0) { /* Child */ printf("Running Child, PID = %d\n", getpid()); while (1) ; /* Infinite loop */ } else { printf("Terminating Parent, PID = %d\n", getpid()); exit(0); }

Ασκήσεις με fork() Αποτέλεσμα

Ασκήσεις με fork() int a=10; if (fork() == 0) { a = a + 5;    printf("%d, %d\n", a, &a); } else     a = a –5;     printf("%d, %d\n", a, &a);

Ασκήσεις με fork() Αποτέλεσμα (πρόκειται για virtual address και όχι για physical):