Σήματα (Signals) Προγραμματισμός II 1

Σχετικά έγγραφα
Σήματα (Signals) Προγραμματισμός II 1

Σήματα (Signals) Προγραμματισμός II 1

Προγραμματισμός συστημάτων UNIX/POSIX. Σήματα (signals)

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

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

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

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

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

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

4 η ιάλεξη: Signals UDP Sockets

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

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

Παράδειγµα χρήσης perror, errno (πρόγραµµα errors_demo.c)

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

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

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

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

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

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

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

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

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

Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1

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

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

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

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

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

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

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

Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1

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

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

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

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

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

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

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

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

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

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

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

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

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

Υλοποίηση Σηματοφόρων

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

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

Προγραμματισμός Ι (HY120)

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

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

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

Προγραμματισμός συστημάτων UNIX/POSIX. Χρονομέτρηση, καθυστέρηση και ανάλυση επιδόσεων

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

Προγραμματισμός Ι (HY120)

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

Κεφάλαιο 11 Διαχείριση Διεργασιών

Νήµαταστην Java. Συγχρονισµός νηµάτων Επικοινωνία νηµάτων Εκτελέσιµα αντικείµενα Νήµατα δαίµονες Οµάδες νηµάτων. Κατανεµηµένα Συστήµατα 11-1

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

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

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

ΠΑΝΕΠΙΣΤΗΜΙΟ AΙΓΑIΟΥ & ΑΕΙ ΠΕΙΡΑΙΑ Τ.Τ. Τμήματα Ναυτιλίας και Επιχειρηματικών Υπηρεσιών & Μηχ. Αυτοματισμού ΤΕ. Εισαγωγή στη Python

Λειτουργικά συστήματα πραγματικού χρόνου

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

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

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

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

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

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

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

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

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

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

Διασυνδεδεμένες Δομές. Λίστες. Προγραμματισμός II 1

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

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

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

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

οµές (structures) Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: Πίνακες δοµών, δείκτες σε δοµές, και αυτοαναφορικές δοµές.

Υπολογισμός - Εντολές Επανάληψης

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Ενδεικτικές λύσεις και στατιστικά

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

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Εντοπισμός τερματισμού. Κατανεμημένα Συστήματα 1

ΕΝΟΤΗΤΑ 4 Λήψη Αποφάσεων και Συναρτήσεις Ελέγχου

Ενώσεις δεδομένων Απαριθμητές Ψηφιακοί τελεστές Αναδρομικές συναρτήσεις

Επικοινωνία με μηνύματα. Κατανεμημένα Συστήματα 1

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

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

Γλώσσες Προγραμματισμού

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

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

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

Dr. Garmpis Aristogiannis - EPDO TEI Messolonghi

Ελεγκτές/Παρακολουθητές (Monitors) Ταυτόχρονος Προγραμματισμός 1

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

Εισαγωγικά & Βασικές Έννοιες

Επικοινωνία αίτησης-απάντησης. Κατανεμημένα Συστήματα 1

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

Transcript:

Σήματα (Signals) Προγραμματισμός II 1 lalis@inf.uth.gr

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

Σήματα σφάλματος SIGFPE: εσφαλμένη αριθμητική λειτουργία (Ε) SIGILL: άκυρη εντολή (Ε) SIGSYS: άκυρη κλήση συστήματος (Ε) SIGBUS: άκυρη διεύθυνση σε επίπεδο υλικού (Ε) SIGSEGV: άκυρη αναφορά μνήμης (Ε) SIGPIPE: γράψιμο σε αγωγό χωρίς αναγνώστη (Τ) Αυτόματες/προεπιλεγμένες ενέργειες (αν δεν γίνει χειρισμός από το πρόγραμμα): Π: παράβλεψη Τ: τερματισμός Ε: Τ + άλλες ενέργειες, π.χ., δημιουργία core dump Α: αναστολή/σταμάτημα εκτέλεσης Σ: συνέχιση εκτέλεσης (μετά από αναστολή) Προγραμματισμός II 3 lalis@inf.uth.gr

Σήματα παραγόμενα με ρητό τρόπο SIGINT: διακοπή από το πληκτρολόγιο (Τ) SIGQUIT: εγκατάλειψη από το πληκτρολόγιο (Ε) SIGHUP: κλείσιμο γραμμής/τερματικού (Τ) SIGTERM: τερματισμός συνθετικά (Τ) SIGKILL: θανάτωση συνθετικά (Τ) SIGUSR1/2: σήματα εφαρμογής (Τ) Αυτόματες/προεπιλεγμένες ενέργειες (αν δεν γίνει χειρισμός από το πρόγραμμα): Π: παράβλεψη Τ: τερματισμός Ε: Τ + άλλες ενέργειες, π.χ., δημιουργία core dump A: αναστολή εκτέλεσης Σ: συνέχιση εκτέλεσης (μετά από αναστολή) Προγραμματισμός II 4 lalis@inf.uth.gr

Σήματα ελέγχου κατάστασης διεργασίας SIGCHLD: αλλαγή κατάστασης παιδιού (Π) SIGSTOP: αναστολή εκτέλεσης διεργασίας (Α) SIGCONT: συνέχιση εκτέλεσης διεργασίας (Σ) SIGΤSTP: αναστολή εκτέλεση από τερματικό (Α) SIGTTIN: ανάγνωση από το παρασκήνιο (Α) SIGTTOU: γράψιμο από το παρασκήνιο (Α) Αυτόματες/προεπιλεγμένες ενέργειες (αν δεν γίνει χειρισμός από το πρόγραμμα): Π: παράβλεψη Τ: τερματισμός Ε: Τ + άλλες ενέργειες, π.χ., δημιουργία core dump A: αναστολή εκτέλεσης Σ: συνέχιση εκτέλεσης (μετά από αναστολή) Προγραμματισμός II 5 lalis@inf.uth.gr

Σύγχρονα και ασύγχρονα σήματα Σύγχρονα σήματα: προκύπτουν ως αποτέλεσμα μιας ενέργειας που επιχείρησε η ίδια η διεργασία Π.χ., εξαίρεση αριθμητικής πράξης (SIGFPE), αναφορά σε άκυρη θέση μνήμης (SIGSEGV), άκυρη εντολή μηχανής (SIGILL) Ασύγχρονα σήματα: προκύπτουν χωρίς να τα έχει προκαλέσει η ίδια η διεργασία με άμεσο τρόπο Π.χ., διακοπή εκτέλεσης (SIGINT), τερματισμός ή αλλαγή κατάστασης διεργασίας παιδιού (SIGCHLD), αναστολή διεργασίας (SIGSTOP) Προγραμματισμός II 6 lalis@inf.uth.gr

Διακοπή εκτέλεσης διεργασίας Τα σήματα διακόπτουν την εκτέλεση της διεργασίας Τα σύγχρονα σήματα διακόπτουν την εκτέλεση ακριβώς στο σημείο του προγράμματος όπου εκτελέστηκε η εντολή που προκάλεσε το σήμα Τα ασύγχρονα σήματα μπορεί να διακόψουν την εκτέλεση ανά πάσα στιγμή Δεν γνωρίζουμε το πόσες φορές μια διεργασία θα λάβει ένα ασύγχρονο σήμα, ούτε γνωρίζουμε το σημείο της εκτέλεσης όπου θα βρίσκεται μια διεργασία όταν λάβει ένα ασύγχρονο σήμα Προγραμματισμός II 7 lalis@inf.uth.gr

χρόνος (α) 1 2 3 4 5 6 7 8 9 10 11 12 13 (β) 1 2 3 4 5 6 7 8 9 10 11 12 13 (γ) 1 2 3 4 5 6 7 8 9 10 11 12 13 Προγραμματισμός II 8 lalis@inf.uth.gr

Κύκλος ζωής ενός σήματος Γέννηση: δημιουργία/αποστολή σήματος Μπλοκάρισμα: αναστολή παράδοσης/χειρισμού του σήματος Παράδοση/παραλαβή: χρονική στιγμή που γίνεται επεξεργασία του σήματος στο πλαίσιο της διεργασίας Χειρισμός: διαδικασία επεξεργασίας του σήματος Προγραμματισμός II 9 lalis@inf.uth.gr

Χειρισμός σήματος Το λειτουργικό ορίζει αυτόματες/προεπιλεγμένες ενέργειες χειρισμού για κάθε τύπο σήματος παράβλεψη σήματος (π.χ., για SIGCHLD) αναστολή εκτέλεσης διεργασίας (π.χ., για SIGSTOP) συνέχεια εκτέλεσης διεργασίας (π.χ., για SIGCONT) τερματισμός διεργασίας (π.χ., για SIGPIPE) Ένα πρόγραμμα μπορεί να «παγιδέψει» ένα σήμα, και να εισάγει «δικές του» ενέργειες χειρισμού αυτόματη/προεπιλεγμένη ενέργεια (SIG_DFL) παράβλεψη σήματος (SIG_IGN) ρουτίνα χειρισμού σήματος εφαρμογής Προγραμματισμός II 10 lalis@inf.uth.gr

signal issued signal pending signal delivery automated handling (OS) explicit handling (user) terminate process ignore signal signal handler Προγραμματισμός ΙΙ 11 lalis@inf.uth.gr

/* X signal handler */ /* Y signal handler */ /* main */ signal X signal Y Προγραμματισμός ΙΙ 12 lalis@inf.uth.gr

Καθορισμός ενεργειών χειρισμού σήματος int sigaction(int signum, const struct sigaction *act, struct sigaction *oact); Καθορίζει ενέργειες χειρισμού για το σήμα signum Οι νέες ενέργειες προσδιορίζονται στην δομή act Οι παλιές ενέργειες χειρισμού αποθηκεύονται στην δομή oact (για μπορεί να γίνει επαναφορά της προηγούμενης κατάστασης) Μπορεί να καθοριστούν διαφορετικές ενέργειες για κάθε ξεχωριστό σήμα Οι ενέργειες για SIGKILL και SIGSTOP δεν αλλάζουν Προγραμματισμός II 13 lalis@inf.uth.gr

Δομή ενεργειών χειρισμού σήματος struct sigaction { void (*sa_handler)(int); sigset_t sa_mask; int sa_flags; void (*sa_sigaction)(int,siginfo_t*,void *); ; Στο sa_handler ανατίθεται ο χειριστής σήματος (SIG_IGN ή SIG_DFL ή δείκτης σε συνάρτηση) το sa_sigaction είναι για σήματα πραγματικού χρόνου Το sa_mask καθορίζει τα σήματα που μπλοκάρονται όταν εκτελείται ο χειριστής σήματος (πλέον του ίδιου του σήματος και όσων είναι ήδη μπλοκαρισμένα) Το sa_flags καθορίζει επιπλέον ιδιότητες π.χ. SA_RESTART για επανεκτέλεση κλήσεων συστήματος Προγραμματισμός II 14 lalis@inf.uth.gr

int main(int argc, char *argv[]) { struct sigaction act = { {0 ; act.sa_handler = SIG_IGN; // ignore signal sigaction(sigint,&act,null); while (1) { printf("going to sleep\n"); sleep(5); Προγραμματισμός ΙΙ 15 lalis@inf.uth.gr

static void handler(int sig) { write(stdout_fileno,"got SIGINT\n",11); int main(int argc, char *argv[]) { struct sigaction act = { {0 ; act.sa_handler = handler; sigaction(sigint,&act,null); while (1) { printf("going to sleep\n"); sleep(5); Προγραμματισμός ΙΙ 16 lalis@inf.uth.gr

Αναμονή παραλαβής/χειρισμού σήματος int sleep(int secs); Μπλοκάρει μέχρι να γίνει χειρισμός ενός σήματος ή μετά την πάροδο του χρονικού διαστήματος secs επιστρέφει 0 αν η διεργασία δεν διακόπηκε από σήμα διαφορετικά, το χρονικό διάστημα που απέμεινε int pause(); Μπλοκάρει μέχρι να γίνει χειρισμός ενός σήματος επιστρέφει -1 με την errno ίση με EINTR Οι pause και sleep επιστρέφουν μόνο για σήματα που χειρίζεται ρητά το πρόγραμμα Προγραμματισμός II 17 lalis@inf.uth.gr

static void handler(int sig) { write(stdout_fileno,"got SIGINT\n",11); int main(int argc, char *argv[]) { struct sigaction act = { {0 ; act.sa_handler = handler; sigaction(sigint,&act,null); while (1) { printf("going to pause\n"); pause(); Προγραμματισμός ΙΙ 18 lalis@inf.uth.gr

Διακοπή κλήσεων συστήματος H παράδοση και χειρισμός ενός ασύγχρονου σήματος μπορεί να διακόψει κάποιες κλήσεις συστήματος Συνήθως, αυτές που μπλοκάρουν την διεργασία Εφόσον γίνει ρητός χειρισμός του σήματος από το πρόγραμμα, η κλήση συστήματος που διακόπηκε αποτυγχάνει με την errno να έχει τιμή EINTR όπως ακριβώς και η pause Αν αυτό δεν είναι επιθυμητό, χρησιμοποιούμε την siginterrupt ή την επιλογή SA_RESTART Προγραμματισμός II 19 lalis@inf.uth.gr

static void handler(int sig) { write(stdout_fileno,"got SIGINT\n",11); int main(int argc, char *argv[]) { int n; char s[ν]; struct sigaction act = { {0 ; act.sa_handler = handler; act.sa_flags = SA_RESTART; sigaction(sigint,&act,null); while (1) { printf("reading from stdin\n"); n = read(stdin_fileno,s,ν-1); if (n > 0) { s[n] = '\0'; printf("%s\n",s); else if (n < 0) { perror("read"); else { printf("end of input\n"); break; return(0); Προγραμματισμός ΙΙ 20 lalis@inf.uth.gr

Σχεδιασμός χειριστών σημάτων Ο χειριστής ενός ασύγχρονου σήματος μπορεί να εκτελεστεί ανά πάσα στιγμή, εμβόλιμα με τον «συμβατικό» κώδικα του προγράμματος Ένας χειριστής σήματος μπορεί να διακοπεί με παρόμοιο τρόπο, για να εκτελεστεί ένας άλλος χειριστής σήματος βλέπε sa_mask Υπάρχουν (λίγες) συγκεκριμένες λειτουργίες που είναι ασφαλείς για (ασύγχρονα) σήματα μπορούν να χρησιμοποιηθούν μέσα σε χειριστές σημάτων Αν ένας χειριστής σήματος χρησιμοποιεί καθολικές μεταβλητές, τότε αυτές πρέπει να δηλώνονται ως volatile sig_atomic_t διαφορετικά μπορεί να προκύψουν προβλήματα ασυνέπειας Προγραμματισμός II 21 lalis@inf.uth.gr

Μπλοκάρισμα σημάτων Η παράδοση και ο αντίστοιχος χειρισμός σημάτων μπορεί να είναι ανεπιθύμητα σε κάποιες περιπτώσεις Τα σήματα μπορεί να μπλοκαριστούν Μέσω της μάσκας μπλοκαρίσματος Τα μπλοκαρισμένα σήματα δεν παραδίδονται στην διεργασία για χειρισμό, αλλά παραμένουν σε εκκρεμότητα μέχρι να ξεμπλοκαριστούν Ο χειρισμός ενός σήματος που βρίσκεται σε εκκρεμότητα γίνεται όταν αυτό ξεμπλοκαριστεί Τα SIGKILL και SIGSTOP δεν μπλοκάρονται Προγραμματισμός II 22 lalis@inf.uth.gr

Λειτουργίες συνόλων σημάτων sigset_t σύνολο σημάτων int sigemptyset(sigset_t *set) αρχικοποίηση κενού συνόλου int sigfillset(sigset_t *set) αρχικοποίηση γεμάτου συνόλου int sigaddset(sigset_t *set, int sig) προσθήκη σήματος στο σύνολο int sigdelset(sigset_t *set, int sig) αφαίρεση σήματος από το σύνολο int sigismember(const sigset_t *set, int sig) έλεγχος για το αν το σήμα ανήκει στο σύνολο Προγραμματισμός II 23 lalis@inf.uth.gr

Καθορισμός μάσκας μπλοκαρίσματος int sigprocmask(int how, const sigset_t *set, sigset_t *oset); Η how προσδιορίζει τον τρόπο αλλαγής της μάσκας μπλοκαρίσματος, με βάση το σύνολο σημάτων set SIG_BLOCK: μπλοκάρισμα των σημάτων του set SIG_UNBLOCK: ξεμπλοκάρισμα των σημάτων του set SIG_SETMASK: αντικατάσταση της μάσκας με το set Στο oset αποθηκεύεται η παλιά τιμή της μάσκας μπλοκαρίσματος για να μπορεί να αποκατασταθεί Προγραμματισμός II 24 lalis@inf.uth.gr

Εξέταση εκκρεμών σημάτων int sigpending(sigset_t *set); Αποθηκεύει στο set τα σήματα που έχουν σταλεί στην διεργασία και βρίσκονται σε εκκρεμότητα Επιστρέφεται πληροφορία για το αν ένα σήμα εκκρεμεί, όχι για το πόσες φορές αυτό έχει σταλεί Το λειτουργικό δεν καταγράφει το πόσες φορές έχει σταλεί ένα μπλοκαρισμένο σήμα, ούτε γίνεται επανειλημμένος χειρισμός του σήματος όταν αυτό ξεμπλοκαριστεί Προγραμματισμός II 25 lalis@inf.uth.gr

static void handler(int sig) { write(stdout_fileno,"got SIGINT\n",11); int main(int argc, char *argv[]) { sigset_t s1,s2; struct sigaction act = { {0 ; act.sa_handler = handler; sigaction(sigint,&act,null); sigemptyset(&s1); sigaddset(&s1,sigint); while (1) { sigprocmask(sig_block,&s1,null); sleep(5); sigpending(&s2); if (sigismember(&s2,sigint)) { printf("sigint is pending\n"); sigprocmask(sig_unblock,&s1,null); sleep(5); Προγραμματισμός ΙΙ 26 lalis@inf.uth.gr

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

Αλλαγή μάσκας και αναμονή σήματος int sigsuspend(const sigset_t *sigmask); Αντικαθιστά την μάσκα μπλοκαρίσματος με το σύνολο σημάτων sigmask και μπλοκάρει μέχρι να παραληφθεί ένα μη μπλοκαρισμένο σήμα για το οποίο υπάρχει ρητός χειρισμός από το πρόγραμμα Όταν παραληφθεί ένα σήμα, αφού γίνει χειρισμός του σήματος, αποκαθίσταται η παλιά μάσκα, και η κλήση επιστρέφει με -1 και errno ίση με EINTR Προγραμματισμός II 28 lalis@inf.uth.gr

Αναμονή για εκκρεμή σήματα int sigwait(const sigset_t *set, int *signum); Μπλοκάρει μέχρι κάποιο από τα σήματα στο set βρεθεί σε εκκρεμότητα Το εκκρεμές σήμα γίνεται αποδεκτό και αποθηκεύεται στην signum Παρότι δεν γίνεται χειρισμός του σήματος, το σήμα που επιστρέφεται θεωρείται παραδομένο Αν υπάρχουν περισσότερα εκκρεμή σήματα, επιστρέφεται ένα από αυτά (απροσδιόριστη επιλογή) Η sigwait επιτρέπει τον ελεγχόμενο χειρισμό σημάτων μέσα από τον συμβατικό κώδικα, χωρίς την εγκατάσταση χειριστών σημάτων Προγραμματισμός II 29 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int sig; sigset_t s; sigemptyset(&s); sigaddset(&s,sigint); sigprocmask(sig_block,&s,null); printf("blocked SIGINT\n"); while (1) { sigwait(&s,&sig); printf("got signal %d\n",sig); Προγραμματισμός ΙΙ 30 lalis@inf.uth.gr

Σήματα και fork / exec Η διεργασία παιδί που δημιουργείται μέσω fork κληρονομεί τους χειρισμούς σημάτων του γονέα κληρονομεί την μάσκα μπλοκαρίσματος δεν κληρονομεί τα εκκρεμή σήματα του γονιού (αρχίζει την εκτέλεση της χωρίς εκκρεμή σήματα) Όταν μια διεργασία αλλάζει κώδικα μέσω exec για τα σήματα που η καθορισμένη ενέργεια είναι SIG_DFL ή SIG_IGN, αυτή παραμένει (το SIGCHLD μπορεί να γίνει SIG_DFL από SIG_IGN, ανάλογα με την υλοποίηση) τα σήματα με χειριστή γυρίζουν σε SIG_DFL γιατί; η μάσκα μπλοκαρίσματος παραμένει ως έχει τα εκκρεμή σήματα παραμένουν ως έχουν Προγραμματισμός II 31 lalis@inf.uth.gr

Παραγωγή/αποστολή σήματος int kill(pid_t pid, int signum); pid > 0: στέλνει το σήμα signum στην διεργασία με αναγνωριστικό pid pid == 0: στέλνει το σήμα signum στην ομάδα διεργασιών το αναγνωριστικό της οποίας είναι το ίδιο με το αναγνωριστικό ομάδας του αποστολέα pid <-1: στέλνει το σήμα signum στην ομάδα διεργασιών το αναγνωριστικό της οποίας είναι ίσο με την απόλυτη τιμή του pid pid == -1: στέλνει το σήμα signum σε όλες τις διεργασίες για τις οποίες έχει άδεια ο αποστολέας Προγραμματισμός II 32 lalis@inf.uth.gr

Συγχρονισμός διεργασιών με σήματα Τα σήματα μπορεί να χρησιμοποιηθούν για να υλοποιηθεί συγχρονισμός μεταξύ διεργασιών Κλασική περίπτωση: «ασύμμετρο ραντεβού» Η διεργασία P2 πρέπει να περιμένει προτού συνεχίσει την εκτέλεση της, μέχρι η διεργασία P1 να ολοκληρώσει μια διαδικασία (τα αποτελέσματα της οποίας πιθανώς επηρεάζουν την διεργασία P2) Υλοποίηση με σήματα: η P1 στέλνει σήμα στην P2, και η P2 περιμένει να λάβει το σήμα για να συνεχίσει την εκτέλεση της Προγραμματισμός II 33 lalis@inf.uth.gr

P1 /* code A */ /*rendez-vous point; other party may proceed */ signal P2 /* code B */ /*rendez-vous point; wait for other party to arrive */ η P1 ειδοποιεί την P2 μέσω σήματος όταν φτάσει σε αυτό το σημείο η P2 πρέπει να περιμένει σε αυτό το σημείο μέχρι να παραλάβει το σήμα Προγραμματισμός ΙΙ 34 lalis@inf.uth.gr

static volatile sig_atomic_t gotsig = -1; static void handler(int sig) { gotsig = sig; int main(int argc, char *argv[]) { pid_t pid; struct sigaction act = { {0 ; if (!(pid=fork())) { act.sa_handler = handler; sigaction(sigusr1,&act,null); while (gotsig == -1) { pause(); // wait for SIGUSR1 printf("this should print second\n"); return(0); τι γίνεται αν το σήμα φτάσει σε αυτό το σημείο; printf("this should print first\n"); kill(pid,sigusr1); return(0); Προγραμματισμός ΙΙ 35 lalis@inf.uth.gr

int main(int argc, char *argv[]) { pid_t pid; struct sigaction act = { {0 ; sigset_t s; sigemptyset(&s); sigaddset(&s,sigusr1); sigprocmask(sig_block,&s,null); if (!(pid=fork())) { act.sa_handler = handler; sigaction(sigusr1,&act,null); τι γίνεται αν το σήμα sigprocmask(sig_unblock,&s,null); φτάσει σε αυτό το σημείο; while (gotsig == -1) { pause(); // wait for SIGUSR1 printf("this should print second\n"); return(0); printf("this should print first\n"); kill(pid,sigusr1); return(0); Προγραμματισμός ΙΙ 36 lalis@inf.uth.gr

int main(int argc, char *argv[]) { pid_t pid; struct sigaction act = { {0 ; sigset_t s,s2; sigemptyset(&s); sigaddset(&s,sigusr1); sigprocmask(sig_block,&s,null); if (!(pid=fork())) { act.sa_handler = handler; sigaction(sigusr1,&act,null); sigfillset(&s2); sigdelset(&s2,sigusr1); sigsuspend(&s2); // wait for SIGUSR1 printf("this should print second\n"); return(0); printf("this should print first\n"); kill(pid,sigusr1); return(0); Προγραμματισμός ΙΙ 37 lalis@inf.uth.gr

int main(int argc, char *argv[]) { pid_t pid; sigset_t s; int signum; sigemptyset(&s); sigaddset(&s,sigusr1); sigprocmask(sig_block,&s,null); if (!(pid=fork())) { sigwait(&s,&signum); // wait for SIGUSR1 printf("this should print second\n"); return(0); printf("this should print first\n"); kill(pid,sigusr1); return(0); Προγραμματισμός ΙΙ 38 lalis@inf.uth.gr

Περισσότερα για την waitpid Η waitpid μπορεί να χρησιμοποιηθεί και για την αναμονή για αλλαγή κατάστασης εκτέλεσης διεργασιών μέσα από αντίστοιχα options WUNTRACED/WCONTINUED: σταμάτημα/ξεκίνημα Αντίστοιχα, μπορεί να γίνει έλεγχος της κατάστασης που αποθηκεύεται στην διεύθυνση status WIFSTOPPED(): true αν η θυγατρική διεργασία ανέστειλε την εκτέλεση της λόγω σήματος WSTOPSIG(): το σήμα που οδήγησε στην αναστολή της εκτέλεσης της θυγατρικής διεργασίας WIFCONTINUED(): true αν η θυγατρική διεργασία συνεχίζει την εκτέλεση της λόγω SIGCONT Προγραμματισμός II 39 lalis@inf.uth.gr

int main(int argc, char *argv[]) { int pid,status,i; pid = fork(); if (pid == 0) { for (i=0; i<20; i++) { printf("going to sleep\n"); sleep(5); return(42); while (1) { waitpid(pid,&status,wuntraced WCONTINUED); if (WIFEXITED(status)) { printf("returned %d\n",wexitstatus(status)); break; else if (WIFSIGNALED(status)) { printf("terminated %d\n",wtermsig(status)); break; else if (WIFSTOPPED(status)) { printf("stopped %d\n",wstopsig(status)); else if (WIFCONTINUED(status)) { printf("continued\n"); return(0); Προγραμματισμός ΙΙ 40 lalis@inf.uth.gr

Ξυπνητήρια int setitimer(int which, const struct itimerval *nval, struct itimerval *oval); ITIMER_REAL: μετράει τον πραγματικό χρόνο, στην λήξη στέλνεται το σήμα SIGALRM ITIMER_VIRTUAL: μετράει τον χρόνο εκτέλεσης της διεργασίας, στην λήξη στέλνεται SIGVTALRM ITIMER_PROF: μετράει τον χρόνο εκτέλεσης της διεργασίας και τον χρόνο εκτέλεσης του συστήματος για λογαριασμό της διεργασίας, στην λήξη στέλνεται το σήμα SIGPROF Στο oval επιστρέφονται οι τρέχουσες ρυθμίσεις Προγραμματισμός II 41 lalis@inf.uth.gr

Δομή χρονισμού ξυπνητηριού struct itimerval { struct timeval it_interval; /*nxt val*/ struct timeval it_value; /*cur val*/ ; struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ ; Το πεδίο it_value καθορίζει/επιστρέφει τον χρόνο που απομένει, και το πεδίο it_interval την τιμή επαναφοράς για τις επόμενες επαναλήψεις Προγραμματισμός II 42 lalis@inf.uth.gr

static void handler(int sig) { write(stdout_fileno,"got SIGALRM\n",12); int main(int argc, char *argv[]) { int n; char s[n]; struct sigaction act = { {0 ; struct itimerval t = { {0 ; act.sa_handler = handler; sigaction(sigalrm,&act,null); t.it_interval.tv_sec=3; t.it_interval.tv_usec=0; t.it_value.tv_sec=5; t.it_value.tv_usec=0; setitimer(itimer_real,&t,null); while (1) { n = read(stdin_fileno,s,n-1); if (n > 0) { s[n] = '\0'; printf("read: %s\n",s); else if (n == 0) { printf("end of input\n"); break; else if (errno!= EINTR) { perror("read"); break; else { printf("interrupted, retrying\n"); return(0); Προγραμματισμός ΙΙ 43 lalis@inf.uth.gr