Αναγν. άρθρου: 317723 - Τελευταία αναθεώρηση: Κυριακή, 29 Μαΐου 2011 - Αναθεώρηση: 4.0

Περιγραφή των όρων ανταγωνισμού και προβλήματα

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

Σε αυτήν τη σελίδα

Ανάπτυξη όλων | Σύμπτυξη όλων

Περίληψη

Visual Basic.NET ή Visual Basic 2005 προσφέρει τη δυνατότητα να χρησιμοποιήσετε νημάτων σε εφαρμογές της Visual Basic για πρώτη φορά. Νήματα εισάγουν ζητήματα εντοπισμού σφαλμάτων όπως συνθήκες ανταγωνισμού και προβλήματα. Αυτό το άρθρο εξετάζει αυτά τα δύο θέματα.

Περισσότερες πληροφορίες

Καταστάσεις ανταγωνισμού

Α κατάσταση κούρσας Συμβαίνει όταν δύο νήματα πρόσβαση σε κοινόχρηστο μεταβλητή ταυτόχρονα. Το πρώτο νήμα διαβάζει τη μεταβλητή και το δεύτερο νήμα διαβάζει την ίδια τιμή από τη μεταβλητή. Στη συνέχεια νήμα πρώτο και δεύτερο νήμα να εκτελέσετε τις εργασίες τους την τιμή και τους Οδηγήστε για να δείτε ποιο νήμα να γράψετε τελευταία την τιμή στη μεταβλητή κοινόχρηστο. Τιμή του νήματος που εγγράφει την τιμή της τελευταίας διατηρείται, επειδή το νήμα εγγραφή της τιμής που δημιούργησε το νήμα προηγούμενη.

Λεπτομέρειες και παράδειγμα

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

Πώς μια εντολή μίας γραμμής μπορεί να προκαλέσει μια κατάσταση κούρσας; Εξετάστε το ακόλουθο παράδειγμα, για να δείτε πώς μια κατάσταση κούρσας παρουσιάζεται. Υπάρχουν δύο νήματα και δύο ενημέρωση ενός κοινόχρηστου μεταβλητή που ονομάζεται σύνολο (που αναπαρίσταται ως DWORD ptr ds: [031B49DCh] στον κώδικα συγκρότησης).

Κώδικα της Visual Basic:
   'Thread 1
   Total = Total + val1
				
   'Thread 2
   Total = Total - val2
				
Συγκρότηση κώδικα (με αριθμούς γραμμών) από την κατάρτιση των παραπάνω κώδικα Visual Basic:
 'Thread 1
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   add         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        7611097F 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
 'Thread 2
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   sub         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        76110BE7 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
Κοιτάζοντας κώδικα συγκρότησης, μπορείτε να δείτε πόσες λειτουργίες ο επεξεργαστής εκτελώντας στο κατώτερο επίπεδο για να εκτελέσετε έναν υπολογισμό απλή Προσθήκη. Ένα νήμα μπορεί να εκτελέσει όλο ή μέρος του κώδικα συγκρότησης κατά την ώρα του επεξεργαστή. Τώρα δείτε πώς μια κατάσταση κούρσας παρουσιάζεται από αυτόν τον κωδικό.

Σύνολο είναι 100, τιμή1 είναι 50 και τιμή2 είναι 15. Νήμα 1 λαμβάνει μια ευκαιρία να εκτελεστεί αλλά ολοκληρώνει μόνο τα βήματα 1 έως 3. Αυτό σημαίνει ότι νήματος 1 Διαβάστε τη μεταβλητή και την ολοκλήρωση της προσθήκης. Νήμα 1 τώρα απλά περιμένει να εγγράψει την νέα τιμή 150. Μετά τη διακοπή του νήματος 1, 2 νήμα λαμβάνει εκτέλεση εντελώς. Αυτό σημαίνει ότι αυτό έχει εγγραφεί η τιμή αυτή υπολογίζεται (85) εκτός στο σύνολο μεταβλητών. Τέλος, το νήμα 1 εν ελέγχου και ολοκλήρωση της εκτέλεσης της. Εγγράφει την τιμή (150). Επομένως, όταν ολοκληρωθεί το νήμα 1, η τιμή του συνολικού είναι τώρα 150 αντί 85.

Μπορείτε να δείτε πώς αυτό μπορεί να είναι ένα σημαντικό πρόβλημα. Εάν αυτό ήταν ένα πρόγραμμα τραπεζών, ο πελάτης θα έχει χρήματα στο λογαριασμό που θα πρέπει να υπάρχει.

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

Για να αποτρέψετε την εμφάνιση συνθήκες ανταγωνισμού, μπορείτε να κλειδώσετε κοινόχρηστο μεταβλητές, έτσι ώστε μόνο ενός νήματος τη φορά έχει πρόσβαση σε κοινόχρηστο μεταβλητή. Αυτό το κάνετε με σύνεση, γιατί αν μια μεταβλητή είναι κλειδωμένο στο νήμα 1 και 2 νήματος πρέπει, επίσης, η μεταβλητή, εκτέλεσης του νήματος 2 σταματά κατά την αναμονή του νήματος 2 για νήματος 1 για να αφήσετε τη μεταβλητή. (Για περισσότερες πληροφορίες, ανατρέξτε στο θέμα "SyncLock" στην ενότητα "Αναφορές" αυτού του άρθρου).

Συμπτώματα

Το πιο κοινό σύμπτωμα για μια κατάσταση κούρσας είναι απρόβλεπτη τιμές μεταβλητών που είναι κοινόχρηστα μεταξύ πολλών νημάτων. Αυτό προκύπτει από τον απρόβλεπτο παράγοντα της εντολής που εκτελεί τα νήματα. Κάποτε ένα νήμα wins και αφορά την υπηρεσία wins νήμα. Άλλες φορές, εκτέλεση λειτουργεί σωστά. Επίσης, εάν εκτελείται ξεχωριστά κάθε νήμα, τιμή μεταβλητής συμπεριφέρεται σωστά.

Προβλήματα

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

Λεπτομέρειες και παράδειγμα

Ο παρακάτω κώδικας έχει δύο αντικείμενα, LeftVal και RightVal:
'Thread 1
SyncLock LeftVal
 SyncLock RightVal
  'Perform operations on LeftVal and RightVal that require read and write.
 End SyncLock
End SyncLock
				
'Thread 2
SyncLock RightVal
 SyncLock LeftVal
  'Perform operations on RightVal and LeftVal that require read and write.
 End SyncLock
End SyncLock
				
Παρουσιάζεται αδιέξοδο όταν το νήμα 1 επιτρέπεται να κλειδώσετε LeftVal. Ο επεξεργαστής σταματά η εκτέλεση του νήματος 1 και ξεκινά η εκτέλεση του νήματος 2. Νήμα κλειδώματα 2 RightVal και, στη συνέχεια, επιχειρεί να κλειδώσει LeftVal. Επειδή είναι κλειδωμένο LeftVal, 2 νήματος σταματά και περιμένει LeftVal να κυκλοφορήσει. Επειδή το νήμα 2 έχει διακοπεί, νήματος 1 επιτρέπεται να συνεχιστεί η εκτέλεση. Νήμα 1 επιχειρεί το κλείδωμα RightVal αλλά δεν είναι δυνατή, επειδή έχει κλειδωθεί από 2 νήματος. Ως αποτέλεσμα, το νήμα 1 ξεκινά να περιμένετε μέχρι να διατεθεί RightVal. Κάθε νήμα περιμένει άλλο νήμα, επειδή κάθε νήμα έχει κλειδώσει τη μεταβλητή που είναι σε αναμονή από άλλο νήμα και ούτε νήματος ξεκλείδωμα μεταβλητή που εκμετάλλευση.

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

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

Συμπτώματα

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

Τι είναι ένα νήμα;

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

Αναφορές

Για περισσότερες πληροφορίες, αναζήτηση στη Βοήθεια της Visual Studio για τις ακόλουθες λέξεις-κλειδιά:
  • SyncLock. Επιτρέπει σε ένα αντικείμενο για να είναι κλειδωμένο. Εάν κάποιο άλλο νήμα προσπαθεί να κλειδώσετε το ίδιο αντικείμενο, αποκλείεται μέχρι το πρώτο νήμα για ενημερωμένες εκδόσεις. Χρησιμοποιήστε SyncLock προσεκτικά, επειδή μπορεί να προκύψουν προβλήματα από την κατάχρηση SyncLock. Για παράδειγμα, αυτή η εντολή μπορεί να αποτρέψει καταστάσεις ανταγωνισμού αλλά προκαλούν προβλήματα.
  • InterLocked. Επιτρέπει την επιλογή σύνολο λειτουργιών νήματος σε βασικές αριθμητικές μεταβλητές.
Για πρόσθετες πληροφορίες, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:
316422  (http://support.microsoft.com/kb/316422/EN-US/ ) ΠΛΗΡΟΦΟΡΙΕΣ: Οδηγίες για τη δημιουργία νημάτων σε Visual Basic.NET
Για περισσότερες πληροφορίες, ανατρέξτε στην ακόλουθη τοποθεσία του MSDN στο Web:
Νήματα και νήματα (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconthreadsthreading.asp)

Οι πληροφορίες σε αυτό το άρθρο ισχύουν για:
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
Λέξεις-κλειδιά: 
kbvs2005swept kbvs2005applies kbinfo kbmt KB317723 KbMtel
Μηχανικά μεταφρασμένοΜηχανικά μεταφρασμένο
ΣΗΜΑΝΤΙΚΟ: Αυτό το άρθρο είναι προϊόν λογισμικού μηχανικής μετάφρασης της Microsoft και όχι ανθρώπινης μετάφρασης. Η Microsoft σάς προσφέρει άρθρα που είναι προϊόντα ανθρώπινης αλλά και μηχανικής μετάφρασης έτσι ώστε να έχετε πρόσβαση σε όλα τα άρθρα της Γνωσιακής Βάσης μας στη δική σας γλώσσα. Ωστόσο, ένα άρθρο που έχει προκύψει από μηχανική μετάφραση δεν είναι πάντα άριστης ποιότητας. Ενδέχεται να περιέχει λεξιλογικά, συντακτικά ή γραμματικά λάθη, όπως ακριβώς τα λάθη που θα έκανε ένας μη φυσικός ομιλητής επιχειρώντας να μιλήσει τη γλώσσα σας. Η Microsoft δεν φέρει καμία ευθύνη για τυχόν ανακρίβειες, σφάλματα ή ζημίες που προκύψουν λόγω τυχόν παρερμηνειών στη μετάφραση του περιεχομένου ή χρήσης του από τους πελάτες της. Επίσης, η Microsoft πραγματοποιεί συχνά ενημερώσεις στο λογισμικό μηχανικής μετάφρασης.
Η αγγλική έκδοση αυτού του άρθρου είναι η ακόλουθη:317723  (http://support.microsoft.com/kb/317723/en-us/ )