ο προγραμματισμός υπολογιστών το μακροπρόθεσμο "νήμα" είναι σύντομο για το νήμα εκτέλεσης, στο οποίο ένας επεξεργαστής ακολουθεί μια καθορισμένη διαδρομή μέσω του κώδικα σας. Η έννοια της παρακολούθησης περισσοτέρων του ενός νήματος κάθε φορά εισάγει το θέμα της πολλαπλών εργασιών και των πολλαπλών σπειρωμάτων.
Μια εφαρμογή έχει μία ή περισσότερες διεργασίες σε αυτήν. Σκεφτείτε μια διαδικασία ως πρόγραμμα που εκτελείται στον υπολογιστή σας. Τώρα, κάθε διαδικασία έχει ένα ή περισσότερα θέματα. Μια εφαρμογή παιχνιδιών μπορεί να έχει ένα νήμα για να φορτώσει πόρους από το δίσκο, ένα άλλο για να κάνει AI και ένα άλλο για να τρέξει το παιχνίδι ως διακομιστής.
Στο .NET / Windows, το λειτουργικό σύστημα διαθέτει χρόνο επεξεργαστή σε ένα νήμα. Κάθε νήμα παρακολουθεί τους διαχειριστές εξαιρέσεων και την προτεραιότητα με την οποία εκτελείται και έχει κάπου να αποθηκεύσει το περιεχόμενο του νήματος μέχρι να τρέξει. Το πλαίσιο νήματος είναι η πληροφορία που χρειάζεται να συνεχιστεί το νήμα.
Πολλαπλών εργασιών με θέματα
Τα νήματα απορροφούν λίγο μνήμη και η δημιουργία τους χρειάζεται λίγο χρόνο, έτσι συνήθως δεν θέλετε να χρησιμοποιήσετε πολλά. Θυμηθείτε, ανταγωνίζονται για χρόνο επεξεργαστή. Εάν ο υπολογιστής σας διαθέτει πολλαπλές επεξεργαστές, τότε τα Windows ή το .NET ενδέχεται να εκτελούν κάθε νήμα σε διαφορετική CPU, αλλά εάν πολλά θέματα τρέχουν στην ίδια CPU, τότε μόνο μία μπορεί να είναι ενεργή κάθε φορά και η αλλαγή των νημάτων παίρνει χρόνος.
Η CPU εκτελεί ένα νήμα για μερικές εκατομμύρια οδηγίες και στη συνέχεια μεταβαίνει σε άλλο νήμα. Όλοι οι καταχωρητές της CPU, το τρέχον σημείο εκτέλεσης του προγράμματος και η στοίβα πρέπει να αποθηκευτούν κάπου για το πρώτο νήμα και στη συνέχεια να αποκατασταθούν από κάπου αλλού για το επόμενο νήμα.
Δημιουργία ενός νήματος
Στο σύστημα ονομάτων. Το νήμα, θα βρείτε τον τύπο του νήματος. Το νήμα του κατασκευαστή (ThreadStart) δημιουργεί μια εμφάνιση ενός νήματος. Ωστόσο, πρόσφατα ΝΤΟ# κώδικα, είναι πιο πιθανό να περάσει σε μια έκφραση lambda που καλεί τη μέθοδο με οποιεσδήποτε παραμέτρους.
Εάν δεν είστε βέβαιοι lambda εκφράσεις, ίσως αξίζει τον έλεγχο του LINQ.
Ακολουθεί ένα παράδειγμα ενός νήματος που δημιουργείται και ξεκινάει:
χρησιμοποιώντας το σύστημα.
χρησιμοποιώντας το σύστημα. Threading;
χώρο ονομάτων ex1
{
class
{
δημόσιο στατικό κενό Write1 ()
{
Κονσόλα. Γράψτε ('1');
Νήμα. Ύπνος (500);
}
static κενό Κύριο (συμβολοσειρά [] args)
{
var task = νέο Θέμα (Write1);
έργο. Έναρξη ();
για (var i = 0; i <10; i ++)
{
Κονσόλα. Γράψτε ('0');
Κονσόλα. Γράψτε (εργασία. Ειναι ΖΩΝΤΑΝΟΣ? 'ΕΝΑ Δ') ;
Νήμα. Ύπνος (150);
}
Κονσόλα. ReadKey ();
}
}
}
Το όλο αυτό το παράδειγμα είναι να γράψετε "1" στην κονσόλα. Το κύριο νήμα γράφει μια "0" στην κονσόλα 10 φορές, κάθε φορά ακολουθούμενη από ένα "A" ή "D" ανάλογα με το αν το άλλο νήμα είναι ακόμα Alive ή Dead.
Το άλλο νήμα τρέχει μόνο μία φορά και γράφει ένα "1." Μετά την καθυστέρηση μισού δευτερολέπτου στο νήμα Write1 (), το νήμα τερματίζεται και η εργασία. Το IsAlive στον κύριο βρόχο επιστρέφει τώρα "Δ."
Βιβλιοθήκη παράλληλης βιβλιοθήκης θεμάτων και εργασιών
Αντί να δημιουργήσετε το δικό σας νήμα, εκτός και αν πραγματικά το χρειάζεστε, χρησιμοποιήστε ένα Pool Thread. Από το .NET 4.0, έχουμε πρόσβαση στην παράλληλη βιβλιοθήκη εργασιών (TPL). Όπως και στο προηγούμενο παράδειγμα, πάλι χρειαζόμαστε λίγο LINQ, και ναι, είναι όλες οι εκφράσεις lambda.
Οι εργασίες χρησιμοποιούν το Ζώνη νήματος πίσω από τις σκηνές, αλλά να χρησιμοποιήσετε καλύτερα τα νήματα ανάλογα με τον αριθμό που χρησιμοποιείται.
Το κύριο αντικείμενο στο TPL είναι μια εργασία. Αυτή είναι μια κλάση που αντιπροσωπεύει μια ασύγχρονη λειτουργία. Ο πιο κοινός τρόπος για να ξεκινήσετε τα πράγματα είναι να εκτελέσετε την εργασία. Εργοστάσιο. StartNew όπως στο:
Εργο. Εργοστάσιο. StartNew (() => DoSomething ());
Όπου DoSomething () είναι η μέθοδος που εκτελείται. Είναι δυνατό να δημιουργήσετε μια εργασία και να μην την εκτελέσετε αμέσως. Σε αυτή την περίπτωση, απλά χρησιμοποιήστε το Task like this:
var t = νέα εργασία (() => Κονσόλα. Γράφημα WriteLine ("Hello")).
...
t. Αρχή();
Αυτό δεν ξεκινάει το νήμα έως ότου καλείται το .Start (). Στο παρακάτω παράδειγμα, υπάρχουν πέντε εργασίες.
χρησιμοποιώντας το σύστημα.
χρησιμοποιώντας το σύστημα. Threading;
χρησιμοποιώντας το σύστημα. Το νήμα. Καθήκοντα;
χώρο ονομάτων ex1
{
class
{
δημόσιο στατικό κενό Write1 (int i)
{
Κονσόλα. Γράψτε (i);
Νήμα. Ύπνος (50);
}
static κενό Κύριο (συμβολοσειρά [] args)
{
για (var i = 0; i <5; i ++)
{
τιμή var = i;
var runningTask = Εργασία. Εργοστάσιο. StartNew (() => Write1 (τιμή));
}
Κονσόλα. ReadKey ();
}
}
}
Εκτελέστε αυτό και παίρνετε τα ψηφία 0 έως 4 σε κάποια τυχαία σειρά όπως το 03214. Αυτό συμβαίνει επειδή η σειρά εκτέλεσης εργασιών καθορίζεται από το .NET.
Μπορεί να αναρωτιέστε γιατί είναι απαραίτητη η τιμή var = i. Δοκιμάστε να την αφαιρέσετε και να καλέσετε την εγγραφή (i) και θα δείτε κάτι απρόσμενο όπως το 55555. Γιατί είναι αυτό? Είναι επειδή η εργασία δείχνει την τιμή του i κατά το χρόνο εκτέλεσης της εργασίας, όχι όταν δημιουργήθηκε η εργασία. Δημιουργώντας ένα νέο μεταβλητός κάθε φορά στον βρόχο, κάθε μία από τις πέντε τιμές είναι σωστά αποθηκευμένη και παραληφθεί.