Skip to content

demetresalx/SystemsProgramming3

Repository files navigation

# 3rd System Programming Assignment 2020
**D. Alexandres, 1115201400006.**
Third (3rd) assignment on UNIX system programming,
*University of Athens, 2020.*

Υλοποιήθηκε με C++ σε Ubuntu 16.04 LTS και δοκιμάστηκε σε μηχάνημα της σχολής.
Στο makefile θα δείτε πως η παράμετρος -Ofast που έχω δε δημιουργεί κανένα πρόβλημα καθώς
η εκτέλεση δεν βασίζεται ΠΟΥΘΕΝΑ σε busy waiting και άρα δεν υπάρχει κίνδυνος απαλοιφής από βελτιστοποιήσεις του compiler.
Όλα τα ερωτήματα/εντολές έχουν υλοποιηθεί.
Δοκιμάστηκε και με τους master,server,client να βρίσκονται σε 3 διαφορετικά μηχανήματα σχολής.

Ο κώδικας είναι ΓΕΜΑΤΟΣ με σχόλια επεξηγηματικά.

ΤΑ PORT NUMBERS GIA QUERIES KAI STATISTICS ΣΤΑ CMD ARGUMENTS ΠΡΕΠΕΙ ΝΑ ΕΙΝΑΙ ΣΩΣΤΑ ΓΙΑ ΕΥΝΟΗΤΟΥΣ ΛΟΓΟΥΣ.

#ΕΝΤΟΛΗ_ΕΚΤΕΛΕΣΗΣ/ΜΕΤΑΓΛΩΤΤΙΣΗΣ
compile with : make
εκτέλεση ίδια με της εκφώνησης για το κάθε πρόγραμμα.

Το master πρόγραμμα ξεκινά τον απαιτούμενο αριθμό workers και τους μοιράζει
τα directores ομοιόμορφα ακριβώς όπως στη 2η εργασία μέσω named pipes.
Παραμένει ζωντανό ώστε να χειρίζεται το SIGCHLD σήμα και να αναγεννά παιδιά-workers όταν κάποιο από
τα υπάρχοντα τερματίσει ξαφνικά. Για έξοδο/τερματισμό του master προγράμματος, αρκεί ctr-C (SIGINT) στον master
και αυτός θα φροντίσει να κάνει SIGKILL και τα παιδιά.

Το κάθε worker process στη συνέχεια δημιουργεί ενα sockaddr_in με port το 0
ώστε να του ανατεθεί μετά ενα διαθέσιμο νούμερο πόρτας για να το στείλει στον whoServer.

O server έχει 2 ports (αυτά που δίνονται ως ορίσματα) "αυτιά" στα οποία ακούει συνδέσεις.
Στο ένα ακούει statistics connections και στο άλλο queries. Διαχωρίζει πότε άκουσε σε ποιο αυτί
με την POLL(). Βλέπει δηλαδή ποιο δέχτηκε σύνδεση, κάνει accept, τοποθετεί ένα tuple(fd της accept, string που λέει αν είναι στατιστικ ή query)
και τα threads του ασχολούνται μαζί του.
Τα threads του server είναι οι consumers του κυκλικού buffer kαι ο server είναι ο παραγωγός με άλλα λόγια.

Επίσης, για να ξέρει ένα server thread ποιον worker πρέπει να ρωτήσει, διατηρείται μια δομή
ορατή από αυτά που κρατάει τις χώρες του κάθε worker, την πόρτα που του όρισε αυτός αρχικά
και την IP του ώστε να μπορεί να κάνει connect σε αυτόν. Αυτή η δομή (worker_db)
ενημερώνεται με συγχρονισμό readers-writer. Υπάρχουν 4 μέθοδοι, 2 για εισαγωγή και έξοδο από reading critical section
της δομής και 2 για εισαγωγή και εξοδο από writing critical section της δομής.
Εξηγείται αναλυτικά στο threadfuns.h & .cpp

Ο circular buffer ειναι ΟΠΩΣ ΣΤΙΣ ΔΙΑΦΑΝΕΙΕΣ. Υπάρχει η κλάση pool(αντιστοιχη της struct pool των διαφανειών του κ. Ντούλα) που κρατάει:
1. τον πίνακα απο fds που ζητείται *
2. το start
3. το end
4. το count
* ο πίνακας αυτός αντί για ένα σκέτο fd έχει μέσα και το τι είδους fd είναι (query or statistics) για να κατατοπίζει τα threads σωστά.
Λειτουργεί όπως στις διαφάνειες με producer τον server που κάνει accept και consumers τα threads του που αναλαμβάνουν να τα εξυπηρετήσουν.

----------ΠΡΩΤΟΚΟΛΛΟ ΕΠΙΚΟΙΝΩΝΙΑΣ ΜΕΣΩ SOCKETS------------
Ίδιο με τα named pipes της 2η εργασίας. Όπως είχα εξηγήσει και εκεί, έχω φτιάξει τις συναρτήσεις
send_string, receive_string που χρησιμοποιούν ΑΠΟΚΛΕΙΣΤΙΚΑ ΤΙΣ LOW LEVEL CALLS READ & WRITE.
Στέλνεται ένας ακέραιος που είναι το μέγεθος του μηνύματος πρώτα και μετά το μήνυμα.
Έχω και έκδοσή τους για std::string της c++ αλλά και πάλι σε επίπεδο sockets/pipes γίνεται με char * (δε γινεται και αλλιώς).
Βασίζονται και πάλι στις readall, writeall της αμερικάνικης έκδοσης του βιβλίου που κατέβασα από το ίντερνετ μια και δεν έχω το κανονικό βιβλίο.
(Marc J. Rochkind - Advanced UNIX Programming (2004, Addison-Wesley Professional) - selida 97).
Η διαφορά με τη 2η άσκηση είναι ότι για να καλύπτω όλες τις ασυμφωνίες αρχιτεκτονικής
μεταξύ απομακρυσμένων μηχανημάτων, ο ακέραιος που στέλνω πριν το μήνυμα δεν είναι int αλλά int32_t
και τον περνάω απο htonl στον writer. O reader τον κάνει ntohl αφού τον διαβάσει.
Με αυτόν τον τρόπο εξασφαλίζεται οτι θα διαβαστεί σωστά.
Έφτιαξα και τις send_integer, receive_integer που είναι μόνο για μεταφορά αριθμών με τον ίδιο τρόπο.
Εάν ο client λάβει ενα ερώτημα κακώς διατυπωμένο, δε θα το προωθήσει στον server kαι θα δώσει σχετικό μήνυμα λάθους.
Το float που απαιτεί το ερώτημα topk, στέλνεται ως string (με 0 δεκαδικά ψηφία όπως ήταν η ενδεικτική εκτύπωση στην εκφώνηση της άσκησης 2).

-Ο server (όταν το ερώτημα που δέχεται ΔΕΝ είναι country specific και άρα ρωτά όλους τους workers)
μέσω της POLL() πετυχαίνει την ταχύτατη ανάγνωση και σύνθεση των αποτελεσμάτων για να τα στείλει στον client.

------------ΣΥΓΧΡΟΝΙΣΜΟΣ ΝΗΜΑΤΩΝ-----------------
Η κλάση synchro_stdout συγχρονίζει την εκτύπωση των threads στο stdout.
Με τις συναρτήσεις cs_start & cs_end δημιουργεί την αρχή και το τέλος ενός critical
section στο stdout ώστε να εκτυπώνει ενα thread τη φορά
και να μην είναι συγκεχυμένο το output στην οθόνη.

Στον client έχουμε (όπως ζητείται), ένα θρεντ ανά γραμμή αρχείου, με την προϋπόθεση ότι numthreads
είναι ο μέγιστος αριθμός από threads που μπορούν να τρέχουν ανά στιγμή. Δηλαδή αν οι γραμμές του αρχείου είναι
πάνω από numThreads, ο client περιμένει να τελειώσουν αυτά και μετά φτιάχνει καινούργια
για να καλύψουν τις υπόλοιπες γραμμές αρχείου.
Για να μη γίνεται επίσης μπέρδεμα κάθε φορά που διαβάζεται μια γραμμή, το main thread
διαβάζει το αρχείο, δημιουργεί ένα thread και του περνάει ως όρισμα την εντολή που διάβασε.
Πριν φτιάξει το επόμενο, βεβαιώνεται οτι το πρώτο πήρε την εντολή. Αυτό γίνεται με μία condition var.
ΤΑ NUMTHREADS THREADS ΞΕΚΙΝΑΝΕ ΟΛΑ ΜΑΖΙ ΟΠΩΣ ΖΗΤΕΙΤΑΙ καθε φορα.

-------------------
Να σημειωθεί ότι για diseaseFrequency & topk-AgeRanges, το date1-date2 το χειρίζομαι όπως κ στην 1η & 2η άσκηση.
Δηλαδή να βρεις τα records στα οποία το entry date είναι μικρότερο από το date2.
 Στην συνέχεια για όσα records έκαναν qualify πετάς όσα το exit date είναι μικρότερο από το date1.
Επίσης δε μπορεί να δοθεί - ως όρισμα ενός date γιατί η εκφώνηση λέει αν είναι το ένα ορισμένο πρέπει να είναι και το άλλο

About

fork, named-pipes, threads, sockets, mutexes...

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages