ΕΘΝΙΚΟ ΚΑΙ ΚΑΠΟΔΙΣΤΡΙΑΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ & ΤΗΛΕΠΙΚΟΙΝΩΝΙΩΝ ΧΕΙΜΕΡΙΝΟ ΕΞΑΜΗΝΟ ΜΑΘΗΜΑ: ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ

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

Εργαστήριο 14. Συγχρονισμός Νημάτων (χρήση pthread_mutex_t, pthread_cond_t)

ΝΗΜΑΤΑ - ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

C: Από τη Θεωρία στην Εφαρμογή

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

ΕΡΓΑΣΤΗΡΙΟ 5 ΣΗΜΕΙΩΣΕΙΣ

Τμήμα Μηχανικών Πληροφορικής Τ.Ε. Σχολή Τεχνολογικών Εφαρμογών Ακαδημαϊκό έτος

Παρουσίαση 5 ης Άσκησης:

Παρουσίαση 5 ης Άσκησης:

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

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

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Η γλώσσα προγραμματισμού C Δυναμική διαχείριση μνήμης

Εκφωνήσεις ασκήσεων εργαστηρίου 2 (pthreads)

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

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

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

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 3 η : Επίλυση Προβληµάτων Χειµερινό Εξάµηνο 2011

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

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός

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

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

Φροντιςτήριο. Linked-List

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

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

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

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

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

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

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

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

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

ΔΙΑΧΕΙΡΙΣΗ ΜΝΗΜΗΣ - ΣΗΜΕΙΩΣΕΙΣ

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

ΣυγχρονισµόςσεΣυστήµατα ΠολλαπλώνΝηµάτων

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΑΣΚΗΣΗ #5 Προτεινόμενη Λύση

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

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

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

Συναρτήσεις. Εισαγωγή

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΕΠΛ 035: οµές εδοµένων και Αλγόριθµοι για Ηλεκτρολόγους Μηχανικούς και Μηχανικούς Υπολογιστών

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

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

Ενότητα 4: «Εισαγωγή στον Προγραμματισμό. Τα πρώτα προγράμματα σε γλώσσα C»

Εργαστήριο 5. Εντολή if και παραλλαγές: if-else, πολλαπλές if, πολλαπλές if-else. Απλές και σύνθετες εντολές. Εντολή switch.

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

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

Υπολογισμός - Εντολές Ελέγχου

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

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

i M-1 1. ij f(i, j) N-1. (pixel) 2. M N (x, y) (x, y ) = 256. R(x, y), G(x, y), B(x, y)

Προγραµµατισµός Νηµάτων. Αρχικοποίηση µιας Φοράς pthread_once_t once_block = PTHREAD_ONCE_INIT; pthread_mutex_t mutex;

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Η γλώσσα προγραμματισμού C Συνδεδεμένες Λίστες

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

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

Σημειώσεις όγδοης εβδομάδας

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

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

Τμήμα Πληροφορικής & Επικοινωνιών

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

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

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

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

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

HY150a Φροντιστήριο 3 24/11/2017

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

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

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

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

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

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

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

Σημειώσεις ένατης εβδομάδας

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

ΘΕΜΑΤΑ ΕΞΕΤΑΣΗΣ ΚΑΙ ΑΠΑΝΤΗΣΕΙΣ ΤΟΥΣ

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

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

υναµική έσµευση Μνήµης (συν.) ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 Εφαρµογή

Συναρτήσεις διαχείρισης αλφαριθμητικών

12. Συναρτήσεις (Μέρος ΙI)

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

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

Εισαγωγή στον Προγραμματισμό (με. τη C)

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

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

Περιγραφή συστήματος «BankAccount»

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

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

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

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

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

Πανεπιστήμιο Πελοποννήσου. Σχολή Θετικών Επιστημών & Τεχνολογίας. Τμήμα Επιστήμης & Τεχνολογίας Υπολογιστών. Προγραμματισμός Ι Εργαστήριο

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Ι. Κεφάλαιο 6ο: Αδιέξοδα

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

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

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

Transcript:

ΕΘΝΙΚΟ ΚΑΙ ΚΑΠΟΔΙΣΤΡΙΑΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ & ΤΗΛΕΠΙΚΟΙΝΩΝΙΩΝ ΧΕΙΜΕΡΙΝΟ ΕΞΑΜΗΝΟ ΜΑΘΗΜΑ: ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ ΔΙΑΧΕΙΡΙΣΗ ΑΔΙΕΞΟΔΩΝ (DEADLOCKS) Γενικά, για τη διαχείριση των αδιεξόδων υιοθετούνται mutexes ώστε να αποτρέψουν πολλαπλά νήματα να προσπελάσουν την κρίσιμη περιοχή τους την ίδια στογμή. Κάποιες φορές όταν κλειδώνουμε ένα mutex πολλαπλά νήματα κρατούν το κλείδωμα με αποτέλεσμα να αποκλείονται αμοιβαία από την κρίσιμη περιοχή τους. Υπάρχουν τέσσερις απαιτήσεις για ένα αδιέξοδο: Mutual exclusion Hold and wait No preemption Circular wait Ένα αδιέξοδο απαιτεί και τις τέσσερις συνθήκες οπότε για να το αποτρέψουμε μπορούμε να αποτρέψουμε οποιαδήποτε από τις τέσσερις συνθήκες. Μια λύση είναι να κλειδώνουμε τους mutexes σε μια σειρά ώστε να αποφεύγουμε την κυκλική αναμονή. Το ακόλουθο παράδειγμα αναδεικνύει το πως μπορει να συμβεί ένα αδιέξοδο. Ο επόμενος κώδικας αναδεικνύει μια συμπεριφορά που εξαρτάται στο περιβάλλον εκτέλεσης και στον scheduler. Όμως με συγχρονισμό θα πέσει σε αδιέξοδο όταν εκτελεστούν τα νήματα thr1, thr2 όπου το thr1 προσπαθεί να κλειδώσει τον mutex ba2 και το thr2 προσπαθεί να κλειδώσει τον mutex ba1 στη συνάρτηση deposit(). Code 1 typedef struct int balance; pthread_mutex_t balance_mutex;

bank_account; typedef struct bank_account *from; bank_account *to; int amount; deposit_thr_args; void create_bank_account(bank_account **ba, int initial_amount) int result; bank_account *nba = malloc(sizeof(bank_account)); if (nba == NULL) nba->balance = initial_amount; result = pthread_mutex_init(&nba->balance_mutex, NULL); if (result) *ba = nba; void *deposit(void *ptr) int result; deposit_thr_args *args = (deposit_thr_args *)ptr; if ((result = pthread_mutex_lock(&(args->from->balance_mutex)))!= 0) /* Not enough balance to transfer */ if (args->from->balance < args->amount) if ((result = pthread_mutex_unlock(&(args->from->balance_mutex)))!= 0) return NULL;

if ((result = pthread_mutex_lock(&(args->to->balance_mutex)))!= 0) args->from->balance -= args->amount; args->to->balance += args->amount; if ((result = pthread_mutex_unlock(&(args->from->balance_mutex)))!= 0) if ((result = pthread_mutex_unlock(&(args->to->balance_mutex)))!= 0) free(ptr); return NULL; int main(void) pthread_t thr1, thr2; int result; bank_account *ba1; bank_account *ba2; create_bank_account(&ba1, 1000); create_bank_account(&ba2, 1000); deposit_thr_args *arg1 = malloc(sizeof(deposit_thr_args)); if (arg1 == NULL) deposit_thr_args *arg2 = malloc(sizeof(deposit_thr_args)); if (arg2 == NULL)

arg1->from = ba1; arg1->to = ba2; arg1->amount = 100; arg2->from = ba2; arg2->to = ba1; arg2->amount = 100; /* Perform the deposits */ if ((result = pthread_create(&thr1, NULL, deposit, (void *)arg1))!= 0) if ((result = pthread_create(&thr2, NULL, deposit, (void *)arg2))!= 0) pthread_exit(null); return 0; Ο επόμενος κώδικας δείχνει τη σώστη λύση όπου υιοθετείται μια σειρά κλειδώματος των mutexes μέσα στη συνάρτηση. Κάθε νήμα κλειδώνει με βάση το bank_account ID που ορίζεται στην αρχικοποίηση του struct. Ο κώδικας αποτρέπει την κυκλική αναμονή. Code 2 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> typedef struct int balance; pthread_mutex_t balance_mutex; unsigned int id; /* Should never be changed after initialized */ bank_account; typedef struct bank_account *from; bank_account *to;

int amount; deposit_thr_args; unsigned int global_id = 1; void create_bank_account(bank_account **ba, int initial_amount) int result; bank_account *nba = malloc(sizeof(bank_account)); if (nba == NULL) nba->balance = initial_amount; result = pthread_mutex_init(&nba->balance_mutex, NULL); if (result!= 0) nba->id = global_id++; *ba = nba; void *deposit(void *ptr) deposit_thr_args *args = (deposit_thr_args *)ptr; int result; if (args->from->id == args->to->id) return; /* Ensure proper ordering for locking */ if (args->from->id < args->to->id) if ((result = pthread_mutex_lock(&(args->from->balance_mutex)))!= 0) if ((result = pthread_mutex_lock(&(args->to->balance_mutex)))!= 0) else if ((result = pthread_mutex_lock(&(args->to->balance_mutex)))!= 0)

if ((result = pthread_mutex_lock(&(args->from->balance_mutex)))!= 0) /* Not enough balance to transfer */ if (args->from->balance < args->amount) if ((result = pthread_mutex_unlock(&(args->from->balance_mutex)))!= 0) if ((result = pthread_mutex_unlock(&(args->to->balance_mutex)))!= 0) return; args->from->balance -= args->amount; args->to->balance += args->amount; if ((result = pthread_mutex_unlock(&(args->from->balance_mutex)))!= 0) if ((result = pthread_mutex_unlock(&(args->to->balance_mutex)))!= 0) free(ptr); return; Code 3 #include <stdio.h> #include <pthread.h> #include <stdlib.h> pthread_mutex_t read_mutex; pthread_mutex_t write_mutex;

void * write(void *temp) char *ret; FILE *file1; char *str; pthread_mutex_lock(&write_mutex); sleep(5); pthread_mutex_lock(&read_mutex); printf("\nfile locked, please enter the message \n"); str=(char *)malloc(10*sizeof(char)); file1=fopen("temp","w"); scanf("%s",str); fprintf(file1,"%s",str); fclose(file1); pthread_mutex_unlock(&read_mutex); pthread_mutex_unlock(&write_mutex); printf("\nunlocked the file you can read it now \n"); return ret; void * read(void *temp) char *ret; FILE *file1; char *str; pthread_mutex_lock(&read_mutex); sleep(5); pthread_mutex_lock(&write_mutex); printf("\n Opening file \n"); file1=fopen("temp","r"); str=(char *)malloc(10*sizeof(char)); fscanf(file1,"%s",str); printf("\n Message from file is %s \n",str); fclose(file1); pthread_mutex_unlock(&write_mutex); pthread_mutex_unlock(&read_mutex); return ret;

main() pthread_t thread_id,thread_id1; pthread_attr_t attr; int ret; void *res; ret=pthread_create(&thread_id,null,&write,null); ret=pthread_create(&thread_id1,null,&read,null); printf("\n Created thread"); pthread_join(thread_id,&res); pthread_join(thread_id1,&res); Code 4 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; // These two functions will run concurrently. void* print_i(void *ptr) pthread_mutex_lock(&mutex1); pthread_mutex_lock(&mutex2); printf("i am in i"); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); void* print_j(void *ptr) pthread_mutex_lock(&mutex2); pthread_mutex_lock(&mutex1); printf("i am in j"); pthread_mutex_unlock(&mutex1); pthread_mutex_unlock(&mutex2);

int main() pthread_t t1, t2; int iret1 = pthread_create(&t1, NULL, print_i, NULL); int iret2 = pthread_create(&t2, NULL, print_j, NULL); while(1) exit(0); //never reached. Ο επόμενος κώδικας μπορεί να αναγνωρίσει πιθανά αδιέξοδα: Code 5 #include <stdio.h> void main() int allocated[15][15],max[15][15],need[15][15],avail[15],tres[15],work[15],flag[15]; int pno,rno,i,j,prc,count,t,total; count=0; printf("\n Enter number of process: "); scanf("%d",&pno); printf("\n Enter number of resources: "); scanf("%d",&rno); for(i=1;i<=pno;i++) flag[i]=0; printf("\n Enter total numbers of each resources: "); for(i=1;i<= rno;i++) scanf("%d",&tres[i]); printf("\n Enter Max resources for each process: "); for(i=1;i<= pno;i++) printf("\n for process %d:",i); for(j=1;j<= rno;j++) scanf("%d",&max[i][j]); printf("\n Enter allocated resources for each process: "); for(i=1;i<= pno;i++)

printf("\n for process %d:",i); for(j=1;j<= rno;j++) scanf("%d",&allocated[i][j]); printf("\n available resources: \n"); for(j=1;j<= rno;j++) avail[j]=0; total=0; for(i=1;i<= pno;i++) total+=allocated[i][j]; avail[j]=tres[j]-total; work[j]=avail[j]; printf(" %d \t",work[j]); do for(i=1;i<= pno;i++) for(j=1;j<=rno;j++) need[i][j]=max[i][j]-allocated[i][j]; printf("\n Allocated matrix Max need"); for(i=1;i<= pno;i++) printf("\n"); for(j=1;j<=rno;j++) printf("%4d",allocated[i][j]); printf(" "); for(j=1;j<=rno;j++)

printf("%4d",max[i][j]); printf(" "); for(j=1;j<=rno;j++) printf("%4d",need[i][j]); prc=0; for(i=1;i<= pno;i++) if(flag[i]==0) prc=i; for(j=1;j<= rno;j++) if(work[j]< need[i][j]) prc=0; break; if(prc!=0) break; if(prc!=0) printf("\n Process %d completed",i); count++; printf("\n Available matrix:"); for(j=1;j<= rno;j++) work[j]+=allocated[prc][j]; allocated[prc][j]=0; max[prc][j]=0; flag[prc]=1;

printf(" %d",work[j]); while(count!=pno&&prc!=0); if(count==pno) printf("\nthe system is in a safe state!!"); else printf("\nthe system is in an unsafe state!!");