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

Σχετικά έγγραφα
Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

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

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

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

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

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

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

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

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

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

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

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

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

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

Βιβλιοθήκη stdio. Προγραμματισμός II 1

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

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

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

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

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

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

Βιβλιοθήκη stdio. Προγραμματισμός II 1

UNIX System Programming

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

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

Συγχρονισμός & σηματοφόροι. Προγραμματισμός II 1

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

Διεργασίες (μοντέλο μνήμης & εκτέλεσης) Προγραμματισμός II 1

Προγραμματισμός Υπολογιστών με C++

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

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

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

Ουρές Μηνυμάτων (Message Queues in System V) Προγραμματισμός II 1

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

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

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

Βιβλιοθήκες Αφηρημένοι τύποι δεδομένων. Προγραμματισμός II 1

Διεργασίες (μοντέλο μνήμης & εκτέλεσης) Προγραμματισμός II 1

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 3-4: Προγραμματισμός MIPS. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

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

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

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

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

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

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

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

Διάλεξη 5: Δείκτες και Συναρτήσεις

Περιγραφείς Αρχείων & Ανακατεύθυνση EE. Προγραμματισμός II 1

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δείκτες και Συναρτήσεις (Κεφάλαιο 11, KNK-2ED)

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

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

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

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

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

Βασικές λειτουργίες συστήματος πάνω σε αρχεία δεδομένων. Προγραμματισμός II 1

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Αντικείμενα ως ορίσματα

IPC System V. Προγραμματισμός II 1

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

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

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

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

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

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Εισαγωγή στο περιβάλλον προγραμματισμού του εργαστηρίου

ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

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

Προγραμματισμό για ΗΜΥ

Μετακινούμενος Κώδικας (Mobile Code) Κατανεμημένα Συστήματα 1

Αντικειµενοστρεφής Προγραµµατισµός

Διδάσκων: Παναγιώτης Ανδρέου

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

Εισαγωγή στο περιβάλλον προγραμματισμού του εργαστηρίου. Λειτουργικά Συστήματα Εργαστήριο Υπολογιστικών Συστημάτων ΕΜΠ

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

Δομημένος Προγραμματισμός (ΤΛ1006)

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Δείκτες σε συναρτήσεις. Προγραμματισμός II 1

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

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

είκτες και Πίνακες (2)

ΤρόποςΑξιολόγησης: α) Εργαστήρια (Προαιρετικάµε 20% - 35% βαρύτητα µόνοθετικά) β) Τελική Γραπτή Εξέταση

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

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

NIKOΛΑΟΣ ΝΤΙΡΛΗΣ 5ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΑΙΘΟΥΣΑ Β4

Προγραμματισμός Υπολογιστών με C++

Η γλώσσα προγραμματισμού C Οι συναρτήσεις στη C (2)

Προεπεξεργαστής C. Προγραμματισμός Ι 1

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Το λειτουργικό σύστημα. Προγραμματισμός II 1

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

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

Ιδιοκτησία Αντικειµένου

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

Το λειτουργικό σύστημα. Προγραμματισμός II 1

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

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

Διδάσκων: Παναγιώτης Ανδρέου

Transcript:

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

Δημιουργία νέας διεργασίας pid_t fork() Η fork δεν έχει παραμέτρους Δημιουργεί μια νέα διεργασία που είναι ένα αντίγραφο της διεργασίας που καλεί την fork Η νέα διεργασία ονομάζεται «παιδί» ή «θυγατρική», και αυτή που την δημιούργησε «γονιός» ή «γονική» Προγραμματισμός II 2 lalis@inf.uth.gr

Κληρονομιά Το παιδί (ως αντίγραφο του γονιού) αρχικοποιείται «κληρονομώντας» την κατάσταση του γονιού Το παιδί εκτελεί τον ίδιο κώδικα με τον γονιό H μνήμη του παιδιού (αν και ξεχωριστή) έχει, αρχικά, τα ίδια περιεχόμενα με αυτήν του γονιού αντίγραφα στατικής μνήμης, δυναμικής μνήμης, στοίβας Ως μέρος της κατάστασης του γονιού, το παιδί «κληρονομεί» και τον program counter συνεπώς, το παιδί αρχίζει την εκτέλεση του από την εντολή που ακολουθεί την κλήση της fork (όχι από την main) Προγραμματισμός II 3 lalis@inf.uth.gr

NEW copy memory copy stack P1 P2 copy memory stack code Προγραμματισμός ΙΙ 4 lalis@inf.uth.gr

P1 (parent) fork() P2 (child) code Προγραμματισμός ΙΙ 5 lalis@inf.uth.gr

Διαχωρισμός γονιού-παιδιού Πως ξεχωρίζουμε, μέσα στον κώδικα, αν βρισκόμαστε στο πλαίσιο εκτέλεσης του γονιού ή του παιδιού; Ελέγχουμε την τιμή που επιστρέφει η fork = 0: για το παιδί > 0: για τον γονιό (αναγνωριστικό του παιδιού) < 0: αποτυχία (δεν δημιουργήθηκε νέα διεργασία) Η τιμή επιστροφής χρησιμοποιείται συνήθως για να γίνει μια διακλάδωση μέσα στον κώδικα έτσι ώστε ο γονιός και το παιδί να εκτελέσουν διαφορετικό τμήμα του κώδικα του προγράμματος Προγραμματισμός II 6 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; printf("creating new process\n"); pid = fork(); printf("%d: hello world\n",getpid()); printf("%d: pid = %d\n",getpid(),pid); return(0); Προγραμματισμός ΙΙ 7 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; printf("creating new process\n"); pid = fork(); if (pid == 0) { printf("%d: hi from child\n",getpid()); else { printf("%d: hi from parent\n",getpid()); return(0); Προγραμματισμός ΙΙ 8 lalis@inf.uth.gr

Μια πρώτη μορφή «επικοινωνίας» Ο γονιός μπορεί να αναθέσει σε κάποιες μεταβλητές (θέσεις μνήμης) τιμές / δεδομένα που επιθυμεί να «περάσει» στο παιδί, προτού δημιουργήσει το παιδί Αμέσως μετά την fork, το παιδί έχει ένα αντίγραφο της μνήμης του γονιού άρα οι μεταβλητές του παιδιού θα έχουν τις ίδιες τιμές με αυτές του γονιού Στην συνέχεια, αφού κάθε διεργασία έχει ξεχωριστή μνήμη, οι όποιες αλλαγές γίνονται στην μνήμη μιας διεργασίας είναι ορατές μόνο στην ίδια δεν υπάρχει κάποια «κρυφή» μετάδοση δεδομένων ανάμεσα στην διεργασία γονιό και την διεργασία παιδί Προγραμματισμός II 9 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; int data = 42; pid = fork(); if (pid == 0) { data = data + 1; printf("child: %d\n", data); return(0); else { data = data - 1; printf("parent: %d\n", data); return(0); Προγραμματισμός ΙΙ 10 lalis@inf.uth.gr

parent memory data 42 code pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; Προγραμματισμός ΙΙ 11 lalis@inf.uth.gr

parent child NEW memory memory data 42 copy 42 data code pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; Προγραμματισμός ΙΙ 12 lalis@inf.uth.gr

parent child memory memory data 42 42 data code pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; Προγραμματισμός ΙΙ 13 lalis@inf.uth.gr

parent child memory memory data 42 42 data code pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; Προγραμματισμός ΙΙ 14 lalis@inf.uth.gr

parent child memory memory data 41 43 data code pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; pid = fork(); if (pid == 0) { data = data + 1; else { data = data 1; Προγραμματισμός ΙΙ 15 lalis@inf.uth.gr

Κρυφή κατάσταση (βιβλιοθηκών) Μέρος της κατάστασης που κληρονομείται στο παιδί είναι και η εσωτερική κατάσταση των βιβλιοθηκών που χρησιμοποιεί ο γονιός τιμές μεταβλητών, ενδιάμεσες αποθήκες δεδομένων, Αυτό μπορεί να προκαλέσει «περίεργα» φαινόμενα Για παράδειγμα, τα περιεχόμενα της εσωτερικής αποθήκης της stdio στον γονιό αντιγράφονται στην εσωτερική αποθήκη της stdio στο παιδί (όπως όλα τα περιεχόμενα της μνήμης του γονιού) Προγραμματισμός II 16 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; printf("hello "); pid = fork(); λόγω line-buffered πολιτικής οι χαρακτήρες αποθηκεύονται εσωτερικά στην stdio if (!pid) { printf("from child\n"); return(0); else { printf("from parent\n"); return(0); και τελικά γράφονται στην καθιερωμένη έξοδο όταν ολοκληρωθεί η γραμμή με \n Προγραμματισμός ΙΙ 17 lalis@inf.uth.gr

Τερματισμός διεργασίας void _exit(int status) τερματίζει την διεργασία άμεσα, κλείνει περιγραφείς αρχείων void exit(int status) κλήση επιπλέον διαδικασιών «καθαρισμού» του χρήστη ισοδυναμεί με κλήση της return από την main Η _exit/exit μπορεί να κληθεί από οποιοδήποτε σημείο του κώδικα του προγράμματος Ο κωδικός κατάστασης status πρέπει να είναι μια τιμή (0..255) ώστε να χωράει σε ένα byte συνήθως EXIT_SUCCESS (0) ή EXIT_FAILURE (1) Ο κωδικός κατάστασης αποθηκεύεται έτσι ώστε να μπορεί να παραληφθεί από την γονική διεργασία Προγραμματισμός II 18 lalis@inf.uth.gr

Αναμονή για τερματισμό παιδιού pid_t waitpid(pid_t pid, int *status, int options) pid > 0: αναμονή για την συγκεκριμένη διεργασία pid == 0: αναμονή για οποιαδήποτε διεργασία βρίσκεται στην ίδια ομάδα με την γονική διεργασία pid == -1: αναμονή για οποιαδήποτε διεργασία pid < -1: αναμονή για οποιαδήποτε διεργασία βρίσκεται στην ομάδα με αναγνωριστικό pid Επιστρέφει το αναγνωριστικό της διεργασίας ή μιας από όλες τις διεργασίες που έχει/έχουν τερματιστεί Προγραμματισμός II 19 lalis@inf.uth.gr

Ερμηνεία της τιμής επιστροφής Στην διεύθυνση status αποθηκεύεται πληροφορία σχετικά με την διεργασία που τερματίστηκε Η τιμή αυτή ερμηνεύεται μέσω μακροεντολών WIFEXITED(): true αν η θυγατρική διεργασία τερματίστηκε κανονικά (με _exit ή exit) WEXITSTATUS(): το λιγότερο σημαντικό byte της τιμής που επεστράφη μέσω _exit ή exit WIFSIGNALED(): true αν η θυγατρική διεργασία δεν τερματίστηκε κανονικά (αλλά μέσω σήματος) WTERMSIG(): ο αριθμός του σήματος που προκάλεσε τον τερματισμό της διεργασίας Προγραμματισμός II 20 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; // child process id int status; // child status pid = fork(); if (pid == 0) { sleep(5); printf("woke up, exiting with result 42\n"); exit(42); // return(42); waitpid(pid,&status,0); if (WIFEXITED(status)) { printf("child returned %d\n", WEXITSTATUS(status)); else { printf("child terminated abnormally\n"); return(0); Προγραμματισμός ΙΙ 21 lalis@inf.uth.gr

Λίγα περισσότερα για την waitpid Στην πραγματικότητα η waitpid επιστρέφει όταν γίνεται μια αλλαγή κατάστασης του παιδιού Υπάρχουν 3 περιπτώσεις: τερματισμός διεργασίας, σταμάτημα μέσω σήματος, ξεκίνημα μέσω σήματος Αν ο γονιός δεν περιμένει για τον τερματισμό ενός παιδιού, αυτό παραμένει σε μια κατάσταση zombie Το λειτουργικό συνεχίζει να κρατά πληροφορία για το παιδί (λόγος τερματισμού, τιμή επιστροφής κλ), για να μπορεί να την παραλάβει ο γονιός αργότερα η πληροφορία κρατιέται μέχρι να τερματιστεί ο γονιός Προγραμματισμός II 22 lalis@inf.uth.gr

Κληρονομιά περιγραφέων αρχείων Μαζί με την κατάσταση εκτέλεσης του γονιού, το παιδί κληρονομεί αντίγραφα των περιγραφέων αρχείων που έχει δημιουργήσει ο γονιός στο πνεύμα της dup Η ανάγνωση/εγγραφή μέσω των περιγραφέων αρχείων της μιας διεργασίας αλλάζουν την θέση ανάγνωσης/εγγραφής των περιγραφέων της άλλης Ο γονιός πρέπει να κλείνει τους περιγραφείς που δεν θέλει να κληρονομήσει το παιδί, και αντίστοιχα το παιδί πρέπει να κλείνει τους κληρονομημένους περιγραφείς αρχείων που δεν χρειάζεται Προγραμματισμός II 23 lalis@inf.uth.gr

διεργασία γονιός 0 1 2 3 file descriptor table access structure access structure access structure Προγραμματισμός ΙΙ 24 lalis@inf.uth.gr

διεργασία γονιός 0 1 2 3 file descriptor table fork access structure access structure access structure file descriptor table διεργασία παιδί 0 1 2 3 Προγραμματισμός ΙΙ 25 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int fd,pid; fd=open(argv[1],o_rdwr O_CREAT O_TRUNC,S_IRWXU); if (!(pid=fork())) { write(fd,"hello from child ",17); close(fd); return(0); waitpid(pid,null,0); /* wait for child to write */ write(fd,"and hello from parent",21); close(fd); return(0); Προγραμματισμός ΙΙ 26 lalis@inf.uth.gr

Αλλαγή κώδικα μιας διεργασίας Μια διεργασία μπορεί να αλλάξει το πρόγραμμα που εκτελεί μέχρι εκείνη τη στιγμή, και να αρχίσει να εκτελεί ένα διαφορετικό πρόγραμμα η διεργασία μένει η ίδια Ένα παιδί μπορεί να «αυτονομηθεί» και να εκτελέσει διαφορετικό κώδικα από αυτόν που εκτελεί ο γονιός συνηθισμένος λόγος για την δημιουργία νέων διεργασιών Το σύστημα είναι ανοιχτό/επεκτάσιμο Μπορεί να γραφτεί κώδικας που κάποια στιγμή «θα» εκτελέσει κώδικα που δεν έχει γραφτεί ακόμα Προγραμματισμός II 27 lalis@inf.uth.gr

Εκτέλεση προγράμματος int execlp(const char *file, const char *arg0, const char *arg1,..., NULL) Εκτελεί το πρόγραμμα file (με βάση το PATH) περνώντας τα ορίσματα arg0, arg1,... Αν πετύχει, η κλήση δεν επιστρέφει ποτέ int execvp(const char *file, char *const argv[]) Όπως η execlp, με τα ορίσματα του προγράμματος να περνιούνται ως διάνυσμα, όπως τα δέχεται η main Προγραμματισμός II 28 lalis@inf.uth.gr

παλιά εκτέλεση νέα εκτέλεση memory memory stack P1 stack code Α code B Προγραμματισμός ΙΙ 29 lalis@inf.uth.gr

P1 exec() code Α code B Προγραμματισμός ΙΙ 30 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int v1,v2; πρόγραμμα add v1=atoi(argv[1]); v2=atoi(argv[2]); printf("%d plus %d equals %d\n",v1,v2,v1+v2); return(0); int main(int argc, char *argv[]) { printf("trying to execute add\n"); execlp("./add","add","123","456",null); perror("execlp"); return(1); Προγραμματισμός ΙΙ 31 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid,status; if (!(pid=fork())) { printf("trying to execute add\n"); execlp("./add","add","123","456",null); perror("execlp"); return(1); waitpid(pid,&status,0); if (WIFEXITED(status)) { printf("child returned %d\n", WEXITSTATUS(status)); else { printf("child terminated abnormally\n"); return(0); Προγραμματισμός ΙΙ 32 lalis@inf.uth.gr

Κατάσταση διεργασίας μετά το exec Όταν μια διεργασία αλλάζει κώδικα μέσω exec, η κατάσταση εκτέλεσης αρχικοποιείται εκ νέου Η διεργασία αποκτά καινούργια μνήμη Η διεργασία αποκτά καινούργια στοίβα Οι βιβλιοθήκες σε επίπεδο χρήστη ξαναφορτώνονται Είναι σχεδόν σα να δημιουργείται μια καινούργια διεργασία που εκτελεί το πρόγραμμα Προγραμματισμός II 33 lalis@inf.uth.gr

Κληρονομιά περιγραφέων αρχείων Οι περιγραφείς αρχείων που διατηρεί η διεργασία μέχρι τη στιγμή που αλλάζει κώδικα μέσω exec παραμένουν ανοιχτοί Το πρόγραμμα που εκτελεί η διεργασία μπορεί να χρησιμοποιήσει αυτούς τους περιγραφείς, σαν να τους είχε δημιουργήσει το ίδιο Κλασική εφαρμογή: ανακατεύθυνση της συμβατικής εισόδου/εξόδου ενός προγράμματος (εν αγνοία του ίδιου του προγράμματος), προτού αρχίσει η εκτέλεση του (μέσω exec) Προγραμματισμός II 34 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int fd,pid,status; if (!(pid=fork())) { fd=open(argv[1],o_rdwr O_CREAT O_TRUNC,S_IRWXU); dup2(fd,stdout_fileno); // redirect stdout close(fd); execlp("./add","add","123","456",null); perror("execlp"); return(1); waitpid(pid,&status,0); if (WIFEXITED(status)) { printf("child returned %d\n", WEXITSTATUS(status)); else { printf("child terminated abnormally\n"); return(0); Προγραμματισμός ΙΙ 35 lalis@inf.uth.gr