Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 46741|Απάντηση: 7

[Πηγή] Πτητικό vs. Αλληλένδετο vs. κλειδαριά

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 27/8/2018 2:40:35 μ.μ. | | |
Ας υποθέσουμε ότι υπάρχει μια κλάση που περιέχει ένα δημόσιο πεδίο μετρητή int στο οποίο μπορείτε να έχετε πρόσβαση από πολλά νήματα και αυτός ο αριθμός θα αυξηθεί ή θα μειωθεί μόνο.

Κατά την προσθήκη αυτού του πεδίου, ποιο από τα παρακάτω σχήματα πρέπει να χρησιμοποιηθεί και γιατί;

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Αλλάξτε τον τροποποιητή πρόσβασης του μετρητή σε δημόσιο πτητικό


Το χειρότερο (κανένα από αυτά δεν λειτουργεί πραγματικά)

Αλλάξτε τον τροποποιητή πρόσβασης του μετρητή σε δημόσιο πτητικό

Αυτή η προσέγγιση στην πραγματικότητα δεν είναι καθόλου ασφαλής και το σημείο σχετικά με το πτητικό είναι ότι πολλαπλά νήματα που εκτελούνται σε πολλαπλές CPU αποθηκεύουν δεδομένα προσωρινής αποθήκευσης και αναδιατάσσουν τις εκτελούμενες εντολές.

Εάν είναι μη πτητική, όταν η CPU A αυξάνεται κατά μια τιμή, η CPU B πρέπει να περιμένει λίγο για να δει την αυξημένη τιμή, κάτι που μπορεί να οδηγήσει σε προβλήματα.

Εάν είναι πτητικό, διασφαλίζει ότι και οι δύο CPU βλέπουν την ίδια τιμή ταυτόχρονα. Αλλά δεν αποφεύγει τις οριζόντιες λειτουργίες ανάγνωσης και εγγραφής.

Η προσθήκη τιμής σε μια μεταβλητή απαιτεί στην πραγματικότητα τρία βήματα

1. Ανάγνωση, 2. Προσθήκη 3. Γράψτε

Ας υποθέσουμε ότι το νήμα Α διαβάζει την τιμή του μετρητή ως 1 και δεν είναι έτοιμο να αυξηθεί, τότε το νήμα Β διαβάζει επίσης την τιμή του μετρητή ως 1 και, στη συνέχεια, και τα δύο νήματα αρχίζουν να εκτελούν αυξητικές λειτουργίες και λειτουργίες εγγραφής. Η τιμή του τελικού μετρητή είναι 2. Αυτό δεν είναι σωστό, και τα δύο νήματα έχουν κάνει μια λειτουργία αύξησης και το σωστό αποτέλεσμα θα πρέπει να είναι 3. Επομένως, η επισήμανση του ως ασταθούς είναι απλώς επικίνδυνος.

Είναι καλύτερα

lock(this.locker) this.counter++;

Με αυτόν τον τρόπο είναι ασφαλές (θυμηθείτε να κλειδώσετε οπουδήποτε θέλετε να αποκτήσετε πρόσβαση σε αυτό.counter, φυσικά). Αποτρέπει οποιοδήποτε άλλο νήμα από την εκτέλεση του κλειδωμένου κώδικα. Και επίσης αποτρέπει το πρόβλημα αλληλουχίας εντολών πολλαπλών CPU που αναφέρθηκε παραπάνω. Το πρόβλημα είναι ότι η κλειδαριά είναι αργή στην απόδοση και εάν χρησιμοποιείτε κλειδαριά σε άλλα άσχετα μέρη, μπορεί να μπλοκάρει τα άλλα νήματα σας.

Καλύτερο

Interlocked.Increment(ref this.counter);

Αυτό είναι ασφαλές και πολύ αποτελεσματικό. Εκτελεί ανάγνωση, αύξηση, εγγραφή τριών πράξεων σε ένα άτομο χωρίς να διακόπτεται στη μέση. Επειδή δεν επηρεάζει άλλο κώδικα, δεν χρειάζεται να θυμάστε κλειδαριές αλλού. Και είναι επίσης πολύ γρήγορο (όπως λέει το MSDN, στις σημερινές CPU, είναι συχνά απλώς μια οδηγία).

Αλλά δεν είμαι απολύτως σίγουρος αν μπορεί επίσης να λύσει το πρόβλημα παραγγελίας εντολών της CPU ή αν πρέπει να χρησιμοποιηθεί σε συνδυασμό με το πτητικό και αυτήν την αύξηση.

Συμπλήρωμα: Ποια προβλήματα λύνει καλά το πτητικό;

Δεδομένου ότι το πτητικό δεν μπορεί να αποτρέψει το multithreading, τι μπορεί να κάνει; Ένα καλό παράδειγμα είναι ότι έχετε δύο νήματα, το ένα γράφει πάντα σε μια μεταβλητή, ας υποθέσουμε ότι αυτή η μεταβλητή είναι queneLength και η άλλη διαβάζει πάντα δεδομένα από αυτήν τη μεταβλητή. Εάν το queueLenght δεν είναι πτητικό, το νήμα Α μπορεί να διαβαστεί 5 φορές, αλλά το νήμα Β μπορεί να δει καθυστερημένα δεδομένα ή ακόμα και δεδομένα με λάθος σειρά. Μια λύση είναι να χρησιμοποιήσετε κλειδαριά, αλλά σε αυτήν την περίπτωση μπορείτε επίσης να χρησιμοποιήσετε πτητικό. Αυτό διασφαλίζει ότι το νήμα Β βλέπει πάντα τα πιο πρόσφατα δεδομένα που γράφτηκαν από το νήμα Α, αλλά αυτή η λογική λειτουργεί μόνο αν δεν το διαβάσετε όταν το γράφετε και αν δεν το γράψετε όταν το διαβάζετε. Μόλις πολλά νήματα θέλουν να κάνουν λειτουργίες ανάγνωσης-τροποποίησης-εγγραφής, πρέπει να χρησιμοποιήσετε το Interlocked ή το κλείδωμα.





Προηγούμενος:Μέθοδος κρυπτογράφησης Java MD5
Επόμενος:Το Linq υλοποιεί μη μέσα και σε ερωτήματα υπό όρους στην SQL
Δημοσιεύτηκε στις 29/8/2018 4:21:42 μ.μ. |
Γεια σας, ο κώδικας που κάνατε νωρίτερα που συνδυάζει στοιβαγμένα ιστογράμματα υψηλών γραφημάτων και ιστογράμματα με δυνατότητα διάτρησης; Θα ήθελα να ρωτήσω αν μπορείτε να στείλετε έναν κωδικό που μπορεί να επεξεργαστεί στη διεπαφή https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light;
Δημοσιεύτηκε στις 29/8/2018 4:22:13 μ.μ. |
Ολόκληρο το δίκτυο είναι απλώς ο πόρος σας.
Δημοσιεύτηκε στις 29/8/2018 4:22:55 μ.μ. |
Γιατί τα προηγούμενα 90 χρόνια πριν δεν μπορούσαν να αφήσουν μήνυμα. Έτσι
Δημοσιεύτηκε στις 29/8/2018 4:40:40 μ.μ. |
Είναι βολικό να προσθέσω στοιχεία επικοινωνίας; Συμβουλευτείτε μαζί σας
 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 15/9/2018 1:10:16 μ.μ. |
ιδιωτικό στατικό int safeInstanceCount = 0; Λειτουργήστε με άτομα
System.Threading.Interlocked.Increment(ref safeInstanceCount); Αυτοαύξηση 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Αυτο-μείον 1
Δημοσιεύτηκε στις 21/5/2020 4:43:54 μ.μ. |
Υποστηρίξτε τον κάτοχο να μοιραστεί
 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 11/6/2020 3:00:16 μ.μ. |
1. Έννοια

Σε περιβάλλον πολλαπλών νημάτων, λειτουργίες που δεν διακόπτονται από μηχανισμούς προγραμματισμού νημάτων. Μόλις ξεκινήσει αυτή η λειτουργία, εκτελείται μέχρι το τέλος, χωρίς διακόπτη περιβάλλοντος (εναλλαγή σε άλλο νήμα) ενδιάμεσα.

2. Τάξη

System.Threading.Interlocked στατική κλάση

3. Συναρτήσεις που χρησιμοποιούνται συνήθως (δείτε τα υπόλοιπα)

1.δημόσια στατική int μείωση (ref int location); Προσδιορίστε την τιμή της καθορισμένης μεταβλητής με τη μορφή ατομικής πράξης και αποθηκεύστε το αποτέλεσμα

Ισοδύναμο με κλειδαριά(obj){i--; }

2. δημόσια στατική int Increment (ref int location). Αυξήστε την τιμή της καθορισμένης μεταβλητής με τη μορφή ατομικής πράξης και αποθηκεύστε το αποτέλεσμα

Ισοδυναμεί με lock(obj){i++; }
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com