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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UNIX System Programming

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Μη ανασταλτική/πολυπλεξία Ε/Ε (non-blocking/multiplexed I/O) Προγραμματισμός II 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Μετατροπή χαρακτήρων ASCII σε αριθμό (atoi) & διάβασμα, και αποθήκευση του περιεχομένου του στη μνήμη. (Διάλεξη. Πανεπιστήμιο Κύπρου

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

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

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

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

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

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

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

Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ

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

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; // child process id printf("creating new process\n"); pid = fork(); printf("this will be printed twice\n"); printf("pid = %d\n",pid); return(0); Προγραμματισμός ΙΙ 7 lalis@inf.uth.gr

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

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

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

parent child NEW memory memory data 42 copy 42 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 11 lalis@inf.uth.gr

parent child memory memory data 42 42 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 12 lalis@inf.uth.gr

parent child memory memory data 42 42 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 13 lalis@inf.uth.gr

parent child memory memory data 42 43 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 14 lalis@inf.uth.gr

parent child memory memory data 42 43 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 15 lalis@inf.uth.gr

parent child memory memory data 42 43 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 16 lalis@inf.uth.gr

parent child memory memory data 41 43 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 17 lalis@inf.uth.gr

parent child memory memory data 41 43 data code fork(); sleep(5); data = data - 1; code data = data + 1; sleep(10); Προγραμματισμός ΙΙ 18 lalis@inf.uth.gr

Κρυφή κατάσταση (βιβλιοθηκών) Μέρος της κατάστασης που κληρονομείται στο παιδί είναι και η εσωτερική κατάσταση των βιβλιοθηκών που χρησιμοποιεί ο γονιός τιμές μεταβλητών, ενδιάμεσες αποθήκες δεδομένων, Αυτό μπορεί να προκαλέσει «περίεργα» φαινόμενα Για παράδειγμα, τα περιεχόμενα της εσωτερικής αποθήκης της stdio στον γονιό αντιγράφονται στην εσωτερική αποθήκη της stdio στο παιδί (όπως όλα τα περιεχόμενα της μνήμης του γονιού) Προγραμματισμός II 19 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 Προγραμματισμός ΙΙ 20 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 21 lalis@inf.uth.gr

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

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

int main(int argc, char *argv[]) { int pid; // child process id pid = fork(); if (pid == 0) { sleep(5); printf("woke up, exiting\n"); return(0); waitpid(pid,null,0); printf("child terminated\n"); return(0); Προγραμματισμός ΙΙ 24 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid; // child process id pid = fork(); if (pid == 0) { sleep(5); printf("woke up, exiting\n"); return(0); waitpid(-1,null,0); printf("child terminated\n"); return(0); Προγραμματισμός ΙΙ 25 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); Προγραμματισμός ΙΙ 26 lalis@inf.uth.gr

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

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

διεργασία γονιός 0 1 2 3 file descriptor table access structure access structure access structure Προγραμματισμός ΙΙ 29 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 Προγραμματισμός ΙΙ 30 lalis@inf.uth.gr

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

int main(int argc, char *argv[]) { int fd,n; char str[20]; fd=open("test",o_rdwr O_CREAT O_TRUNC,S_IRWXU); if (!fork()) { write(fd,"hello from child",16); close(fd); return(0); waitpid(-1,null,0); /* wait for child to write */ lseek(fd,-(off_t)16,seek_cur); n=read(fd,str,16); str[n]='\0'; printf("%s\n",str); close(fd); return(0); Προγραμματισμός ΙΙ 32 lalis@inf.uth.gr

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

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

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

int main(int argc, char *argv[]) { int v1,v2; πρόγραμμα add v1=atoi(argv[1]); v2=atoi(argv[2]); printf("add: %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); Προγραμματισμός ΙΙ 37 lalis@inf.uth.gr

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

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

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

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