ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

Σχετικά έγγραφα
Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής

Εργαστήριο ΔΙΕΡΓΑΣΙΕΣ - ΔΙΑΧΕΙΡΙΣΗ

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Θέτοντας και επιστρέφοντας την τιµή της προτεραιότητας διεργασίας

Προγραμματισμός συστημάτων UNIX/POSIX. Διεργασίες (processes)

Παράλληλη Επεξεργασία

Λειτουργικά Συστήματα (Λ/Σ)

Προγραμματισμός συστημάτων UNIX/POSIX. Διαδιεργασιακή επικοινωνία: αγωγοί (IPC inter-process communication: pipes)

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ. Διεργασίες και Νήματα Εργαστηριακές Ασκήσεις

UNIX System Programming

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος

Αγωγοί/Σωλήνες (Pipes) Προγραμματισμός II 1

Χρονοδρομολογητής Κυκλικής Επαναφοράς

Διαδιεργασιακή επικοινωνία (inter-process communication IPC) Προγραμματισμός II 1

Λειτουργικά Συστήματα

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ I

Λειτουργικά Συστήματα. Ενότητα # 10: Προγραμματισμός UNIX Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής

Λειτουργικά Συστήματα (ΗΥ321)

Δίκτυα Επικοινωνιών ΙΙ: Network Programming UDP Sockets, Signals

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

Εκφωνήσεις ασκήσεων εργαστηρίου 1

Εισαγωγή εκτελέσιμου κώδικα σε διεργασίες

Εργαστήριο 5 fork(), exec(), signals

ΑΡ Χ Ε Ι Α Κ Ε Ι Μ Ε Ν Ο Υ (text files)

Εργαστήριο 7 fork(), exec(), signals

Δομημένος Προγραμματισμός

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Ντίρλης Νικόλαος- ΕΤΥ 2 ο Φροντιστήριο Παρασκευή, 18/10/2013 Β4. Λειτουργικά Συστήματα- Φροντιστήριο 2

Διεργασίες και Νήματα (1/2)

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

$./jms console -w <jms in> -r <jms out> -o <operations file> namedpipe. (standard input).

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

Διαχείριση Διεργασιών και Διαδιεργασιακή Επικοινωνία

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκό Έτος

1. Εισαγωγή. Λειτουργικά Συστήματα Η/Υ. Διεργασίες. Ορισμός ΚΕΦΑΛΑΙΟ 3 - ΔΙΕΡΓΑΣΙΕΣ. Κεφάλαιο 3 «Διεργασίες»

Προγραμματισμός Ι (ΗΥ120)

Λειτουργικά Συστήματα

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ

Διάλεξη 18η: Διαχείρηση Αρχείων

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Ανάπτυξη και Σχεδίαση Λογισμικού

ΙΩΑΝΝΗΣ ΚΩΝΣΤΑΝΤΙΝΟΥ 2ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΠΑΡΑΣΚΕΥΗ 26 ΟΚΤΩΒΡΙΟΥ 2012 ΑΙΘΟΥΣΑ Β4

Τµήµα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών Σεπτέµβριος 2013

Εισαγωγή στον Προγραμματισμό

Μεθόδων Επίλυσης Προβλημάτων

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Λειτουργικά Συστήματα

Εργαστήριο 9: Αρχεία

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διαχείριση Διεργασιών και Διαδιεργασιακή Επικοινωνία

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Τεχνολογία και Προγραμματισμός Υπολογιστών. Η γλώσσα προγραμματισμού C

Λειτουργικά Συστήματα (ΗΥ-345) Χειμερινό Εξάμηνο

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκό Έτος

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Κεφάλαιο VΙ: Προσπέλαση Αρχείων. 5.1 Αρχεία δεδομένων.

Εργαστήριο Λειτουργικών Συστημάτων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Προγραμματισμός συστημάτων UNIX/POSIX

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ ΔΙΕΡΓΑΣΙΕΣ

... s12 s13 s14. Σχήμα1: ΙεραρχίαΔιεργασιώνμε l=3καιβάθος d=3. Οκάθεεργάτης(worker)δουλεύειμετο 1/27του αρχείου των ψήφων.

Λειτουργικά Συστήματα

Λειτουργικά Συστήματα. Τ.Ε.Ι. Ιονίων Νήσων Σχολή Διοίκησης και Οικονομίας - Λευκάδα

ιεργασίες και νήµατα Προγραµµατισµός ΙΙΙ 1 lalis@inf.uth.gr

Προγραμματισμός συστημάτων UNIX/POSIX

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. ( ιάλεξη 13) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Επεξεργασία Αρχείων Κειµένου

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκό Έτος

ΑΡΧΕΙΑ ΚΕΙΜΕΝΟΥ ΣΤΗΝ C

Δομές Ανακυκλώσεων. Εντολές ελέγχου - 1

ΕΠΕΞΕΡΓΑΣΙΑ ΑΡΧΕΙΩΝ Λέµε αρχείο

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Η βασική συνάρτηση προγράμματος main()

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

ιαφάνειες παρουσίασης #6 (β)

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος

Νήµατα. Πολύ σηµαντικό

Ανάπτυξη και Σχεδίαση Λογισμικού

Ανάπτυξη και Σχεδίαση Λογισμικού

Προγραμματισμός Ι. Προεπεξεργαστής. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Ε-85: Ειδικά Θέµατα Λογισµικού

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

waitpid(), read(), write(), pipe(), mkfifo() κ.α.).

Προγραμματισμός Ι (ΗΥ120)

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκό Έτος

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Ι

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκό Έτος Κανονική Εξέταση Λύσεις

Περιεχόμενα. Πρόλογος... 21

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Διάλεξη 14: Διεργασίες: Έλεγχος & Σήματα (Processes: Control & Signals)

Προγραμματισμός συστημάτων UNIX/POSIX. Ανακατευθύνσεις (redirections)

Transcript:

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact: nifantop@unipi.gr

Περιεχόμενα ενότητας Διεργασίες Κλήσεις δημιουργίας και τερματισμού διεργασιών Επικοινωνία διεργασιών μέσω σωληνώσεων (pipes) 2

Διεργασίες 3

Έννοια της διεργασίας Με τον όρο διεργασία στο UNIX εννοούμε τη δυναμική πράξη της εκτέλεσης ενός προγράμματος από κάποιο χρήστη. Στα συστήματα UNIX κάθε διεργασία βλέπει τον δικό της εικονικό χώρο διευθύνσεων, ο οποίος στα μάτια κάθε διεργασίας ξεκινά από το 0 και περιλαμβάνει συνήθως διευθύνσεις των 32 bits. Οι διεργασίες είναι ανεξάρτητες Το ΛΣ απομονώνει τις διεργασίες Οι διεργασίες μπορεί να συνεργάζονται Μηχανισμοί επικοινωνίας και συγχρονισμού

Χώρος διευθύνσεων Ο χώρος διευθύνσεων μιας διεργασίας υποδιαιρείται σε 3 τμήματα: 1. Το τμήμα κειμένου (text segment) περιέχει τον κώδικα του προγράμματος που εκτελεί εκείνη τη στιγμή η διεργασία και ξεκινά από τη διεύθυνση 0 του εικονικού χώρου διευθύνσεων. Τα περιεχόμενα του τμήματος κειμένου δεν μπορούν να τροποποιηθούν από τη διεργασία (read-only segment). 2. Το τμήμα δεδομένων (data segment) όπου αποθηκεύονται τα στατικά δεδομένα της διεργασίας (παγκόσμιες μεταβλητές, πίνακες, κλπ.). Το αρχικό μέγεθος του τμήματος αυτού καθορίζεται στο χρόνο μετάφρασης και μπορεί να μεταβληθεί μέσα από το πρόγραμμα, αν προκύψει ανάγκη κατά τη διάρκεια της εκτέλεσής του 3. Το τμήμα στοίβας (stack segment) χρησιμοποιείται για τη στοίβα της διεργασίας. Εκεί φυλάγονται διευθύνσεις επιστροφής, τοπικές μεταβλητές, κλπ. Το τμήμα στοίβας ξεκινά από την ψηλότερη θέση του εικονικού χώρου διευθύνσεων και μετακινείται προς τα κάτω. Το μέγεθος του αυξάνεται αυτόματα από το σύστημα.

Διεργασία γονέας-διεργασία παιδί Οι διεργασίες στο UNIX είναι οργανωμένες σε ένα δένδρο διεργασιών. Όταν μια διεργασία δ1 δημιουργεί μια άλλη διεργασία δ2, η δ2 γίνεται διεργασία-παιδί της δ1 στο δένδρο, και η δ1 είναι η διεργασία-γονέας (parent process) της δ2. Στη ρίζα του δένδρου αυτού βρίσκεται η διεργασία με όνομα init, η οποία είναι ουσιαστικά η αρχική διεργασία του ΛΣ.

Αριθμός ταυτότητας διεργασίας Κάθε διεργασία έχει συσχετισμένο μαζί της έναν εγγυημένα μοναδικό αριθμό ταυτότητας διεργασίας (process-id, pid) που παρέχεται δυναμικά από το σύστημα. Ο αριθμός αυτός μπορεί να περαστεί σαν παράμετρος σε ορισμένες πρωτογενείς κλήσεις προκειμένου να αναφερθούμε σε κάποια διεργασία μέσα από κάποια άλλη. Μια διεργασία μπορεί να μάθει τον αριθμό ταυτότητάς της εκτελώντας την κλήση: #include <sys/types.h> #include <unistd.h> pid_t getpid(void);

Κλήσεις δημιουργίας και τερματισμού διεργασιών

Γέννηση μιας δημιουργίας Η γέννηση μιας διεργασίας στο UNIX είναι διαδικασία δυο βημάτων: Πρώτα η διεργασία-πατέρας δημιουργεί μια νέα διεργασία-παιδί, πιστό αντίγραφο του εαυτού της (κλήση fork()). Στη συνέχεια, η διεργασία-παιδί που προέκυψε αντικαθιστά το πρόγραμμα που εκτελεί (αρχικά ίδιο με του πατέρα) με το νέο πρόγραμμα (κλήση exec()). Προαιρετικά, ο πατέρας μπορεί να περιμένει μέχρι τον τερματισμό κάποιας διεργασίας-παιδιού του (κλήση wait()). Ο οικειοθελής τερματισμός μιας διεργασίας μπορεί να γίνει με την κλήση exit()

Η Κλήση fork() Η κλήση fork() δημιουργεί μια νέα διεργασία, πιστό αντίγραφο της διεργασίας-γονέα και έχει τη μορφή: #include <sys/types.h> #include <unistd.h> pid_t fork(void); Οι δυο διεργασίες μοιράζονται το ίδιο τμήμα κειμένου, ενώ το τμήμα δεδομένων της νέας διεργασίας αποτελεί πιστό αντίγραφο του τμήματος δεδομένων της διεργασίας-γονέα. Επίσης, η νέα διεργασία μοιράζεται όλα τα ανοικτά αρχεία και σωληνώσεις του γονέα. Η μόνη διαφορά ανάμεσα στις 2 διεργασίες είναι η τιμή pid που επιστρέφει η κλήση fork()

Παράδειγμα if ( (pid=fork() == 0 ) { /* Διεργασία-παιδί */ for (i=1; i<=n; i++) printf( Hello from the child (%d)\n, i); } else { /* Διεργασία-γονέας */ printf( Child pid: %d\n, pid); for (i=1; i<=n ; i++) printf( Greetings from the parent (%d)\n, i);

Η κλήση exec() Αντικατάσταση κώδικα: κλήσεις exec Φόρτωση νέου κώδικα και δεδομένων Δεν αλλάζει το PID της διεργασίας Τα ανοιχτά αρχεία παραμένουν Τυπικός κύκλος ζωής διεργασίας 12

Παραλλαγές της 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[]); Όνομα αρχείου, παράμετροι εισόδου, περιβάλλον 13

Η κλήση execl() Η κλήση execl() προκαλεί την εκτέλεση ενός νέου προγράμματος το οποίο αντικαθιστά τα τμήματα κειμένου, δεδομένων και στοίβας του καλούντος προγράμματος Το αρχικό (καλούν) πρόγραμμα χάνεται οριστικά από τη μνήμη και η ίδια διεργασία συνεχίζεται με την εκτέλεση ενός νέου προγράμματος Τα αρχεία που είχε ανοίξει το αρχικό πρόγραμμα παραμένουν ανοικτά και κατά την εκτέλεση του νέου προγράμματος. Παράδειγμα: execl( /bin/ls, ls, -l, (char *)0);

Η κλήση wait() Η κλήση wait() αναστέλλει την εκτέλεση του καλούντος προγράμματος μέχρις ότου τερματισθεί (ομαλά ή ανώμαλα) η εκτέλεση κάποιας από τις διεργασίες-παιδιά του. Αν κάποια διεργασία-παιδί έχει ήδη τερματιστεί, τότε η κλήση επιστρέφει αμέσως -1. Η κλήση wait() επιστρέφει έναν αριθμό στην μεταβλητή status. Σε περίπτωση που η διεργασίαπαιδί τερματίστηκε ομαλά με την κλήση exit(), τα 8 σημαντικότερα ψηφία του αριθμού αυτού παρέχουν την κατάσταση τερματισμού (exit status) της διεργασίας-παιδί Παράδειγμα: #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status); Αποτέλεσμα: exit status = status >> 8; Αν τερματιστεί βίαια η διεργασία τότε θα βγάλει 8 ψηφία με τον κωδικό του σήματος: signal_type = status & 0xFF;

Η κλήση exit() Κάθε διεργασία κατά τον τερματισμό της επιστρέφει έναν κωδικό εξόδου (exit code) ώστε να μπορεί να διαπιστωθεί ο λόγος και ο τρόπος τερματισμού της. Η κλήση exit() κλείνει αυτόματα όλα τα ανοικτά αρχεία της διεργασίας και απελευθερώνει όλα τα τμήματα μνήμης που είχε δεσμέσει κατά τη διάρκεια της εκτέλεσής της. Όταν μια διεργασία τερματιστεί, δεν καταστρέφεται ολοκληρωτικά αλλά παραμένει στην τερματισμένη κατάσταση (zombie state). Όταν ο πατέρας εκτελέσει την κλήση wait() και συλλέξει τον κωδικό εξόδου, η διεργασία καταστρέφεται ολοκληρωτικά, ελευθερώνοντας την εγγραφή του πίνακα διεργασιών που είχε Παράδειγμα: #include <unistd.h> void exit(int status); */το status=0, όταν έχουμε κανονικό τερματισμό της διεργασίας */

Επικοινωνία διεργασιών μέσω σωληνώσεων (pipes) 17

Σωληνώσεις (pipes) Ο μοναδικός μηχανισμός δια μέσω του οποίου δύο ή περισσότερες διεργασίες μπορούν να επικοινωνήσουν στο UNIX είναι οι σωληνώσεις (pipes). Ένα απλό παράδειγμα σωλήνωσης στο φλοιό ανάμεσα σε 2 διεργασίες είναι: ls wc */ παίρνει το αποτέλεσμα της ls και το εισάγει στο wc*/

Σωληνώσεις (pipes) Για να δημιουργήσουμε μια σωλήνωση εκτελούμε την κλήση: #include <unistd.h> int pipe(int pd[2]); Η κλήση pipe() επιστρέφει δυο περιγραφητές αρχείων στα στοιχεία pd[0] και pd[1] του πίνακα pd. Ο περιγραφητής pd[1] χρησιμοποιείται για εγγραφή δεδομένων στο ένα άκρο της σωλήνωσης, ενώ ο pd[0] χρησιμοποιείται για ανάγνωση δεδομένων από το άλλο άκρο της. Oι διεργασίες-παιδιά κληρονομούν όλους τους περιγραφητές αρχείων του πατέρα, μαζί με τις σωληνώσεις. Με τη κλήση write(pd[1], ) οι διεργασίες-παιδιά μπορούν να γράφουν δεδομένα στη σωλήνωση, σαν να έγραφαν σε κάποιο κοινό αρχείο Με τη κλήση read(pd[0], ) μπορούν να διαβάσουν δεδομένα από το άλλο άκρο της σωλήνωσης

Παράδειγμα Να γραφεί πρόγραμμα το οποίο να δημιουργεί μια σωλήνωση pd και στη συνέχεια N διεργασίες-παιδιά. Οι διεργασίες-παιδιά να στέλνουν από ένα μήνυμα στον γονέα και στη συνέχεια να τερματίζουν την εκτέλεσή τους. Ο γονέας να διαβάζει όλα τα μηνύματα από το άλλο άκρο της σωλήνωσης, να τα τυπώνει στη standard έξοδο με τη σειρά που τα διαβάζει και να τερματίζει τον εαυτό του.

Λύση #define BUFSIZ 100 #define Ν 10 /* Αριθμός παιδιών */ int pd[2]; main() { int i, n; char buf[bufsiz]; if ( pipe(pd) < 0 ) error( can t open pipe ); for (i=1; i<=n; i++) if ( fork() == 0 ) child(i); /* Δημιουργία παιδιών */ close(pd[1]); /* Κλείσιμο άκρου εγγραφής */ printf( FATHER: I receiνed from children:\n\n ); while ( (n=read(pd[0], buf, BUFSIZ)) > 0 ) write(1, buf, n); /* 1=stdout */ close(pd[0]); } child(int i) { char buf[bufsiz]; close(pd[0]); /* Κλείσιμο άκρου ανάγνωσης */ sprintf(buf, Ηello from child %2d (pid=%5d)\n, i, getpid()); write(pd[1], buf, strlen(buf)+1); close(pd[1]); exit(0); }

Βήματα εκτέλεσης της λύσης 1. Η διεργασία-γονέας εκτελεί την κλήση pipe(). 2. Η διεργασία-γονέας δημιουργεί διεργασίες-παιδιά μέσω κλήσεων fork(). 3. Οι διεργασίες-παιδιά κλείνουν το άκρο ανάγνωσης της σωλήνωσης. 4. Η διεργασία-γονέας κλείνει το άκρο εγγραφής της σωλήνωσης. 5. Μεταφέρονται δεδομένα μέσω κλήσεων read() και write(). 6. Κάθε διεργασία κλείνει τα άκρα της σωλήνωσης που παρέμειναν ανοικτά.

root@oslab:~$ sudo shutdown h now