sir ImPeCaBlE Δημοσ. 31 Αυγούστου 2018 Δημοσ. 31 Αυγούστου 2018 (επεξεργασμένο) Στο μάθημα Ταυτόχρονου προγραμματισμού της σχολής βλέπω ο καθηγητής ζητάει να υλοποιήσουμε συναρτήσεις up(binary semaphore) και down(binary semaphore) χρησιμοποιώντας της συναρτήσεις της pthread mutex_init, mutex_lock και mutex_unlock. Κοιτάζοντας το man της lock βλέπω: "If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results." που αν έχω καταλάβει καλά, είναι κάτι που πρέπει να κάνει ένας σηματοφόρος. Φτιάχνω τις συναρτήσεις (δε βάζω κώδικα γιατί είναι μέρος άσκησης). Χονδρικά ένα struct με 2 mutex και ένα int. Στο int κρατάω τη τιμή του σηματοφόρου (0 ή 1), ένα mutex για τη προστασία της τιμής και ένα ακόμα για να κάνω μπλοκάρω το thread. Tις χρησιμοποιώ για να υλοποιήσω ένα sleeping barber αλγόριθμο που έχει στις διαλέξεις. Φαίνεται να δουλεύει και μου κάνει εντύπωση. Τυχαίνει ή δεν εμπίπτει στο undefined behaviour του quote? Spoiler #include "../bsem.h" #include <unistd.h> #define N 20 int array[N]; int customer_array_pointer = 0; int avl = 0; sem mtx, sleep_sem; void *barber(); void *customer(void *t); int main (int argc, char *argv[]){ init(&mtx, 1); init(&sleep_sem,0); pthread_t barber_thread; if(pthread_create(&barber_thread, NULL, barber, NULL)){ printf("error thread1\n"); return EXIT_FAILURE; } pthread_t *customer_thread = malloc(sizeof(pthread_t)*N); //Max N customers int time; printf("Enter customer time\n"); scanf("%d", &time); int i =0; while(time!=0 && i<N){ if(pthread_create(&customer_thread[i], NULL, customer, (void *)&time)){ printf("error thread1\n"); return EXIT_FAILURE; } i++; printf("Enter customer time\n"); scanf("%d", &time); } pthread_join(barber_thread, NULL); return EXIT_SUCCESS; } void *customer(void *t){ down(&mtx); array[customer_array_pointer]= *(int *)t; customer_array_pointer++; avl++; if (avl == 0) { up(&sleep_sem); } up(&mtx); return NULL; } void *barber(){ int j=0; while(1){ down(&mtx); avl--; if(avl == -1){printf("sleeping\n"); up(&mtx); down(&sleep_sem); up(&mtx); } up(&mtx); for (int i=0;i<array[j];i++){ printf("working for client: %d with time: %d. Time remaining: %d\n", j, array[j], array[j]-i); sleep(1); } j++; } return NULL; } Αυτό που καταλαβαίνω είναι ότι το thread του barber κλειδώνει το mutex του sleep_sem (όταν δεν υπάρχει πελάτης διαθέσιμος) και το ξεκλειδώνει το πρώτο thread customer. Επεξ/σία 31 Αυγούστου 2018 από sir ImPeCaBlE
παπι Δημοσ. 4 Σεπτεμβρίου 2018 Δημοσ. 4 Σεπτεμβρίου 2018 Ub ειναι επειδη δεν υπαρχει περίπτωση να κανεις unlock και να εχεις γραψει σωστο κωδικα. Γιατι να κανεις unlock ενα mutex που δεν εχει γινει lock;
sir ImPeCaBlE Δημοσ. 4 Σεπτεμβρίου 2018 Μέλος Δημοσ. 4 Σεπτεμβρίου 2018 "If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results." Για το bold ήταν η απορία μου. Δηλαδή στο παράδειγμα του sleeping barber, το mutex του sleep_sem κλειδώθηκε από το thread του barber αλλά ξεκλειδώθηκε από ένα thread customer. Και φαίνεται να δουλεύει χωρίς θέμα. Και σε άλλα προγραμματάκια που δοκίμασα, λειτούργησε όπως περίμενα. Τέσπα, από ότι καταλαβαίνω είναι ub αλλά ταυτόχρονα "δουλεύει" γιατί βλέπω λύσεις στο github από συμφοιτητές μου και όλοι παρόμοια λύση έχουμε. Ίσως έχει ειπωθεί κάτι στα φροντιστήρια του μαθήματος, που δεν τα παρακολούθησα.
παπι Δημοσ. 4 Σεπτεμβρίου 2018 Δημοσ. 4 Σεπτεμβρίου 2018 Αν ειναι να κλειδωνεις ενα mutex στο α νημα, και να το ξεκλειδωνεις στο β νημα, τοτε το "φαινεται να δουλευει" μεταφραζεται σε δεν δουλευει.
sir ImPeCaBlE Δημοσ. 4 Σεπτεμβρίου 2018 Μέλος Δημοσ. 4 Σεπτεμβρίου 2018 Καλά ναι. Μάλλον θα είναι κάποια σύμβαση του μαθήματος για τη συγκεκριμένη εργασία.
defacer Δημοσ. 4 Σεπτεμβρίου 2018 Δημοσ. 4 Σεπτεμβρίου 2018 Δεν καταλαβαίνω πολλά πράγματα εδώ, αλλά το βασικότερο είναι το εξής. Λες ότι το manual αναφέρει XYZ για μια function, την οποία δε βλέπω να καλεί πουθενά ο κώδικας που δίνεις (έκανα find το όνομα της). Άρα τι σχέση έχει το ένα με το άλλο;
sir ImPeCaBlE Δημοσ. 4 Σεπτεμβρίου 2018 Μέλος Δημοσ. 4 Σεπτεμβρίου 2018 Οι mutex_lock και mutex_unlock χρησιμοποιούνται στις συναρτήσεις μου down(*sem) και up(*sem). Το sem είναι το struct που περιγράφω στο πρώτο ποστ. Δεν έβαλα το κώδικα για τις συναρτήσεις γιατί είναι άσκηση του μαθήματος. Αφού όμως τελικά υπάρχουν ήδη λύσεις στο github αν είναι να βοηθήσει, τις κάνω ένα cp. Δε νομίζω ότι έχει ιδιαίτερο νόημα όμως. Χονδρικά όταν καλείται η down(*sem) ουσιαστικά γίνεται mutex_lock για το mutex_t του struct sem. Και όταν καλείται η up(*sem), αν έχει προηγηθεί κλήση της mutex_lock τότε εκτελείται mutex_unlock για το mutex_t του struct sem.
marios28 Δημοσ. 4 Σεπτεμβρίου 2018 Δημοσ. 4 Σεπτεμβρίου 2018 Στις 31/8/2018 στις 11:10 ΜΜ, sir ImPeCaBlE είπε Αυτό που καταλαβαίνω είναι ότι το thread του barber κλειδώνει το mutex του sleep_sem (όταν δεν υπάρχει πελάτης διαθέσιμος) και το ξεκλειδώνει το πρώτο thread customer. Σωστά καταλαβαίνεις εκτός από το εξής: Η sleep_sem δεν είναι mutex. Mutex είναι η mtx. Διάβασε εδώ: https://www.geeksforgeeks.org/mutex-vs-semaphore/ και εδώ: (από Λειτουργικά Συστήματα του Tanenbaum): http://web.cecs.pdx.edu/~harry/Blitz/OSProject/p3/SleepingBarberProblem.pdf
sir ImPeCaBlE Δημοσ. 5 Σεπτεμβρίου 2018 Μέλος Δημοσ. 5 Σεπτεμβρίου 2018 (επεξεργασμένο) Και οι 2 struct sem είναι, οπότε ουσιαστικά mutex . Τουλάχιστον στην υλοποίησή μου. Η mtx θα μπορούσε να είναι ένα απλό mutex αλλά έτσι και αλλιώς δε δημιουργεί πρόβλημα. Επεξ/σία 5 Σεπτεμβρίου 2018 από sir ImPeCaBlE
defacer Δημοσ. 5 Σεπτεμβρίου 2018 Δημοσ. 5 Σεπτεμβρίου 2018 (επεξεργασμένο) Δεν ξέρω, πολύ μπέρδεμα, μισές πληροφορίες και γενικά δύσκολο να βγει άκρη τι κάνεις εκεί. Δεν καταλαβαίνω ούτε με ποια λογική μπορεί να θες να κάνεις αυτό που γράφεις στο αρχικό ποστ, ότι ένα θρεντ κλειδώνει και ένα άλλο ξεκλειδώνει. By definition murex κλειδώνεις, κάνεις μια δουλειά και αμέσως ξεκλειδώνεις. Πάντα στο ίδιο θρεντ. Πας να χρησιμοποιήσεις το mutex σαν κάποιου είδους event? Επεξ/σία 5 Σεπτεμβρίου 2018 από defacer
sir ImPeCaBlE Δημοσ. 5 Σεπτεμβρίου 2018 Μέλος Δημοσ. 5 Σεπτεμβρίου 2018 (επεξεργασμένο) Εγώ θέλω να φτιάξω δυαδικούς σηματοφόρους χρησιμοποιώντας mutex. My bad. Μπερδευτήκαμε πολύ. Βάζω την εκφώνηση: "Υλοποιήστε, ως ξεχωριστό τμήμα λογισμικού στο πνεύμα μιας βιβλιοθήκης, τους δικούς σας δυαδικούς σηματοφόρους, χρησιμοποιώντας mutexes και τις λειτουργίες mutex_init, mutex_lock και mutex_unlock της βιβλιοθήκης pthreads. Επιχειρηματολογήστε για το αν η υλοποίηση σας εγγυάται δικαιοσύνη." H βιβλιοθήκη μου έχει 3 συναρτήσεις: init(*sem), up(*sem), down(*sem). Το sem είναι το struct που ανέφερα δηλαδή 1 int και 2 pthread_mutex_t. Τον ένα mutex το χρησιμοποιώ όταν πειράζω/ελέγχω το int του struct. Το άλλο το χρησιμοποιώ για να μπλοκάρω και να ξεμπλοκάρω το νήμα (προφανώς από άλλο νήμα άρα καταλήγω σε ub). Δε μπορώ να σκεφτώ άλλη υλοποίηση με βάση την εκφώνηση. Επεξ/σία 5 Σεπτεμβρίου 2018 από sir ImPeCaBlE
defacer Δημοσ. 5 Σεπτεμβρίου 2018 Δημοσ. 5 Σεπτεμβρίου 2018 (επεξεργασμένο) Γενικά μιλώντας, με "κλασικό" mutex αυτό που θες δεν γίνεται (εδώ έχεις UB), ή τέλος πάντων γίνεται μόνο με απαράδεκτο τρόπο (busy wait). At this stage έχω αρχίσει να σκέφτομαι πως απλά αυτός που έβαλε την άσκηση αγνοεί τελείως το UB της υπόθεσης προκειμένου να σας βάλει να σκεφτείτε πώς θα κάνετε κάτι αγνοώντας ότι ποτέ κανένας δε θα έπρεπε να κάνει αυτό το κάτι με αυτόν τον τρόπο. Το οποίο κατά την άποψη μου είναι ντιπ ηλίθιο. Επεξ/σία 5 Σεπτεμβρίου 2018 από defacer
imitheos Δημοσ. 5 Σεπτεμβρίου 2018 Δημοσ. 5 Σεπτεμβρίου 2018 (επεξεργασμένο) Στις 4/9/2018 στις 9:13 ΠΜ, sir ImPeCaBlE είπε "If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results." Για το bold ήταν η απορία μου. Edit: Έσβησα το χαλασμένο μήνυμα. Ολόκληρη η απάντηση παρακάτω. Επεξ/σία 5 Σεπτεμβρίου 2018 από imitheos
sir ImPeCaBlE Δημοσ. 5 Σεπτεμβρίου 2018 Μέλος Δημοσ. 5 Σεπτεμβρίου 2018 Ασκήσεις με ενεργή αναμονή είχε στο προηγούμενο set ασκήσεων, οπότε δε νομίζω ότι θέλει κάτι τέτοιο τώρα. Τέσπα, αυτό το μάθημα είναι τελείως εισαγωγικό, οπότε μάλλον κάτι σαν αυτό που λες θα ισχύει. Επίσης όπως είπα: Στις 4/9/2018 στις 9:13 ΠΜ, sir ImPeCaBlE είπε Ίσως έχει ειπωθεί κάτι στα φροντιστήρια του μαθήματος, που δεν τα παρακολούθησα.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα