Page 1 of 1

Java threading

Posted: Tue May 01, 2007 11:21 am
by HdkiLLeR
Ιδιαίτερα αναλυτικό άρθρο: http://www-128.ibm.com/developerworks/j ... 7javatsync σχετικά με threads στην Java και τις διαφορές στο coding style όταν χρησιμοποιούμε real time threads. Aξίζει να του ρίξετε μια ματιά.

Posted: Tue May 01, 2007 11:47 am
by Zifnab
thx HdkiLLeR ! Διαβάζω αυτό τον καιρό αρκετά πάνω στο java multi-threading...

Η βασική μου απορία που ακόμα με βασανίζει είναι η διαφορά ανάμεσα σε ένα program μία process και ένα thread...
Ένα πρόγραμμα μπορεί να αποτελείται από πολλά processes και κάθε process από πολλά threads ή το έχασα?

Υπάρχει τρόπος να φτιάξουμε processes στην java που να τρέχουν ψευδοταυτόχρονα?

Posted: Tue May 01, 2007 7:12 pm
by HdkiLLeR
Zifnab wrote: Η βασική μου απορία που ακόμα με βασανίζει είναι η διαφορά ανάμεσα σε ένα program μία process και ένα thread...
Ένα πρόγραμμα μπορεί να αποτελείται από πολλά processes και κάθε process από πολλά threads ή το έχασα?
Λοιπόν θα προσπαθήσω να το ξεκαθαρίσω, εάν κατάλαβα καλά τι ρωτάς.

1)Το program είναι το αποτέλεσμα του compilation. Ένα σύνολο απο εκτελέσιμες εντολές packaged σε ένα συγκεκριμένο executable format (.exe για win, elf για linux, a.out για παλιότερα unix και .class για java).

2)Tο process χαρακτηρίζει κάθε αυτόδύναμη εκτελέσιμη οντότητα που ζεί (γεννιέται,λειτουργεί και πεθαίνει) στο λειτουργικό. Κάθε ξεχωριστό program που εκτελείς είναι ένα process. Το ίδιο το process απο μόνο του μπορεί να ξεκινήσει άλλα processes. Για παράδειγμα στο Unix το πρώτο program που εκτελείται είναι το init (αυτό στην συνέχεια ξεκινάει όλα τα υπόλοιπα) και φυσικά είναι και το πρώτο process. Τα processes χαρακτηρίζονται απο το process id (pid) και συνεπώς το init έχει pid = 1. Κάθε process όπως σου είπα και παραπάνω μπορεί να κάνει spawn (να γενήσει κατα κάποιο τρόπο - αυτό αναφέρεται και σαν fork σε unix περιβάλλοντα) και άλλα processes (με pids 2,3,4...). Όλα τα ενεργά processes τρέχουν ταυτόχρονα* στο PC σου. Κάθε ξεχωριστό process έχει το δικό του code space στην μνήμη (δηλαδή τον χώρο που υπάρχει ο εκτελέσιμος κώδικας του), το δικό stack (για τις ενεργοποιήσεις των συναρτήσεων/μεθόδων) και το δικό του heap (για να δεσμεύει δυναμικά μνήμη). Εάν τώρα ένα process γεννήσει πολλές φορές τον εαυτό του, να φτιάξει δηλαδή πολλά child processes (πχ πρόκειται για έναν παράλληλο αλγόριθμο που φτιάχνει πολλά instances για να επεξεργαστεί κάθε παράλληλο κομμάτι ένα υποσύνολο του input του) τότε κάθε ένα απο αυτά τα child process για να τρέξει ξεχωριστά απαιτεί απλά δικό του stack αλλά και heap (για να έχουν διαφορετικά data οι τοπικές μεταβλητές και να μπορεί να δουλέψει η παραλληλία). Μαζί με αυτά (heap και stack) θα αντιγράφεται στην μνήμη για κάθε child process και το code part, παρά το γεγονός ότι παραμένει το ίδιο**.

*)Εάν έχεις μία CPU τρέχουν παράλληλα αλλιώς ψευδοπαράλληλα.

**)Το κομμάτι εντολών δεν μπορεί να αλλάξει σε κανένα OS για λόγους ασφαλείας. Εαν έτσι απλά άλλαζαν τo executable part ενός προγράμματος τότε τα virusses θα ήταν trivial στο να γραφτούν.

3)To thread είναι εντελώς διαφορετική ένοια απο το process. Εάν το δούμε απο πολύ ψηλά (αφηρημένα) είναι στην ουσία ένας πιο light τρόπος για να παραλληλήζεις κώδικα. Αρχικά όπως και στην παραπάνω περίπτωση θα υπάρχει ένα process το οποίο θα γεννήσει πολλά threads. Τα threads όμως δεν είναι ξεχωριστά processes (δεν αποκτά το καθένα απο αυτά ξεχωριστό pid και δεν έχει το καθένα δικό του heap, stack και code parts). Συνεπώς πολύ εύκολα (αφού δεν αντιγράφεις κομμάτια στην μνήμη) μπορείς να παραλληλίσεις τον κώδικα σου. Απο την άλλη ο προγραμματισμός είναι πολυπλοκότερος μιας και η χρήση atomic εντολών αλλά και locks είναι επιβεβλημένη. Αυτό είναι γιατί τα threads τεχνικά είναι πολλαπλές ροές εκτέλεσης οι οποίες τρέχουν πάνω στον ίδιο κώδικα, οπότε δεν υπάρχουν ξεχωριστές μεταβλητές ή δομές δεδομένων και πολλαπλά threads μπορεί παράλληλα να πειράζουν τις ίδιες δομές με αποτέλεσμα να υπάρχει πιο εύκολα η πιθανότητα τα έρθεις σε deadlocks, race conditions, starvations κλπ κλπ. Το πλεονεκτημα τους είναι το μικρό overhead για το initialization (σε αντίθεση με τo fork νέων processes) αλλά και η ευκολία επικοινωνίας μεταξύ threads (αφού μοιράζονται το ίδιο memory space μπορεί μια δομή δεδομένων όπως ανέφερα παραπάνω να την πειράζουν περισσότερα απο ένα thread instances και συνεπώς να επικοινωνούν - γράφει κάτι το ένα thread ένα άλλο περιμένει και όταν το πρώτο το γράψει μπορεί να το διαβάσει κλπ κλπ). Στην περίπτωση επικοινωνίας μεταξύ processes, κάτι που αναφέρεται σαν Inter-Process Communication (IPC) τα πράγματα δεν είναι τόσο απλά και για να επικοινωνήσουν δύο processes μέσα στο παιχνίδι μπαίνει το ίδιο το λειτουργικό (κάτι που επιφέρει τρομερό overhead σε σχέση με τα threads).
Zifnab wrote: Υπάρχει τρόπος να φτιάξουμε processes στην java που να τρέχουν ψευδοταυτόχρονα?
Εδώ το έχασα λιγάκι. Όλα τα threads τρέχουν ψευδοπαράλληλα εκτός και εάν έχεις κάνει κάποιο lock και έχεις φτιάξει το δικό του scheduling μηχανισμό με αποτέλεσμα να ορίζεις εσύ ρητά ότι δεν θα τρέχουν παράλληλα.

Posted: Tue May 01, 2007 10:03 pm
by Zifnab
Πολύ κατατοπιστικό το post σου- Αν και δεν το κατανόησα πλήρως που είναι λογικό - θα το ξαναεπισκεπτώ όταν θα έχω αποκτήσει τις γνώσεις που μου λείπουν - Many thnx ! ;) ;) ;)
Όσο για την τελευταία μου ερώτηση - εννοώ πως στην java έμαθα πως να κάνω threads, αλλά δεν μπορώ να φτιάξω processes που συνεργάζονται ψευδοπαράλληλα η μία με την άλλη. Αυτή η τελευταία δυνατότητα μήπως δίνεται μόνο μέσω του OS?
*)Εάν έχεις μία CPU τρέχουν παράλληλα αλλιώς ψευδοπαράλληλα.
Eννοείς διπλοπύρηνη έτσι ? :roll:

Posted: Wed May 02, 2007 10:46 am
by tsilochr
Zifnab wrote:Όσο για την τελευταία μου ερώτηση - εννοώ πως στην java έμαθα πως να κάνω threads, αλλά δεν μπορώ να φτιάξω processes που συνεργάζονται ψευδοπαράλληλα η μία με την άλλη. Αυτή η τελευταία δυνατότητα μήπως δίνεται μόνο μέσω του OS?
Επικοινωνία μεταξύ thread του ίδιου process μπορείς να πετύχεις γράφοντας κατάλληλα το κώδικα σου.

Αν θέλεις να επιτύχεις επικοινωνία μεταξύ διαφορετικών διεργασιών (processes), αυτή θα πρέπει να επιτευχθεί με μεσάζοντα το λειτουργικό. Στο μάθημα των λειτουργικών μαθένετε πως να δουλεύτε με pipes και messages του Unix. Στα Windows υπάρχει το IPC (interprocess communication protocol) και οι ουρές μηνυμάτων (message queues)

Posted: Wed May 02, 2007 10:56 am
by fo@
tsilochr wrote: Αν θέλεις να επιτύχεις επικοινωνία μεταξύ διαφορετικών διεργασιών (processes), αυτή θα πρέπει να επιτευχθεί με μεσάζοντα το λειτουργικό. Στο μάθημα των λειτουργικών μαθένετε πως να δουλεύτε με pipes και messages του Unix. Στα Windows υπάρχει το IPC (interprocess communication protocol) και οι ουρές μηνυμάτων (message queues)
Για επικοινωνία διεργασιών μέσω Java θα μπορούσες σε ποιο χαμηλό επίπεδο να χρησιμοποιήσεις sockets γιατί τα άλλα νομίζω δεν είναι και πολύ διαθέσιμα.

Posted: Wed May 02, 2007 11:58 am
by HdkiLLeR
Zifnab wrote: Όσο για την τελευταία μου ερώτηση - εννοώ πως στην java έμαθα πως να κάνω threads, αλλά δεν μπορώ να φτιάξω processes που συνεργάζονται ψευδοπαράλληλα η μία με την άλλη. Αυτή η τελευταία δυνατότητα μήπως δίνεται μόνο μέσω του OS?
Ναι κοίτα για αυτό σου απάντησα ήδη μέσα απο το προηγούμενο post. Όπως σου είπα εφ' όσον τα threads μπορείς να τα φανταστείς όχι σαν διαφορετικά processes αλλά ένα process με πολλαπλά σημεία εκτέλεσης τα οποία μοιράζονται το ίδιο memory space, για να τα κάνεις να συγχρονιστούν θέλεις απλά μια δική σου δομή δεδομένων (μπορεί να είναι και μια απλή μεταβλητή). Όλα τα threads θα κοιτάνε αυτή και ανάλογα με την τιμή της θα πράτουν τα ανάλογα (μπορείς εάν θέλεις να μεταβιβάζεις και μυνήματα έτσι - πχ γράφει σε ένα string κάτι το ένα thread και μετά ένα άλλο το διαβάζει). Εάν θέλεις να τα συντονίσεις χρονικά τότε μπορείς να το κάνεις πάλι με τέτοιο τρόπο. Όπως σου είπα και πρίν αυτό που πρέπει να προσέξεις είναι θέματα deadlock ή race conditions. Γενικά κοίτα και αυτό εδώ θα σε βοηθήσει: http://www-128.ibm.com/developerworks/l ... hread.html
Zifnab wrote: Eννοείς διπλοπύρηνη έτσι ? :roll:
Ναι και στα διπλοπύρηνα αλλά κυρίως αναφερόμουν σε πραγματικά συστήματα με παραπάνω απο μία CPU.