Κοινή χρήση τεχνολογίας

Γλώσσα Go --- Ταυτόχρονα κανάλια προγραμματισμού (διπλό κανάλι, μονοκάναλο) και παραδείγματα εφαρμογών (καταναλωτής παραγωγού, μοντέλο εκτυπωτή)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Κανάλι

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

Το κανάλι τύπου αναφοράς είναι μια συγκεκριμένη υλοποίηση του τρόπου λειτουργίας CSP και χρησιμοποιείται για πολλαπλή επικοινωνία γορουτίνας. Εφαρμόζει συγχρονισμό εσωτερικά για να εξασφαλίσει ασφάλεια ταυτόχρονης χρήσης.

τύπο καναλιού

Όπως ο χάρτης, το κανάλι είναι επίσης μια αναφορά στην υποκείμενη δομή δεδομένων που δημιουργείται από τη μάρκα.
Όταν αντιγράφουμε ένα κανάλι ή το χρησιμοποιούμε για τη μετάδοση παραμέτρων συνάρτησης, απλώς αντιγράφουμε μια αναφορά καναλιού, έτσι ο καλών και ο καλούμενος θα αναφέρονται στο ίδιο αντικείμενο καναλιού. Όπως και άλλοι τύποι αναφοράς, η μηδενική τιμή του καναλιού είναι μηδενική.
Όταν ορίζετε ένα κανάλι, πρέπει επίσης να ορίσετε τον τύπο των τιμών που αποστέλλονται στο κανάλι. Τα κανάλια μπορούν να δημιουργηθούν χρησιμοποιώντας την ενσωματωμένη συνάρτηση make():

make (chan Type)
make (chan Type,capacity)
  • 1
  • 2
  • Όταν η χωρητικότητα = 0, το κανάλι δεν αποθηκεύεται στην προσωρινή μνήμη και μπλοκάρει την ανάγνωση και την εγγραφή όταν η χωρητικότητα > 0, το κανάλι έχει μια κρυφή μνήμη και δεν μπλοκάρεται μέχρι να συμπληρωθούν τα στοιχεία χωρητικότητας.
  • Το Chamnel λαμβάνει και αποστέλλει δεδομένα μέσω του τελεστή <- Η σύνταξη για την αποστολή και τη λήψη δεδομένων είναι:
channel<-value   //发送value 到channel
<-channel     //接收并将其丢弃
x:=<-channel   //从 channel 中接收数据,并賦偵给x
x,ok:=<-channel   //功能同上,同时检查通道是否已关闭或者是否为空
  • 1
  • 2
  • 3
  • 4

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

ολοκληρώσει

Εισαγάγετε την περιγραφή της εικόνας εδώ

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

Εφαρμογή συγχρονισμού και αλληλεπίδρασης δεδομένων μέσω καναλιών

Εισαγάγετε την περιγραφή της εικόνας εδώ
Εισαγάγετε την περιγραφή της εικόνας εδώ

κανάλι χωρίς προσωρινή αποθήκευση

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

  • Δηλαδή, το ίδιο το κανάλι δεν μπορεί να αποθηκεύσει πράγματα, αν βάλεις κάτι σε ένα, μπορείς να το βγάλεις αμέσως.
  • Στο βήμα 1, και οι δύο γορουτίνες φτάνουν στο κανάλι, αλλά κανένα δεν αρχίζει να στέλνει ή να λαμβάνει.
  • Στο βήμα 2, η γορουτίνα στα αριστερά φτάνει στο χέρι της στο κανάλι, το οποίο προσομοιώνει την πράξη αποστολής δεδομένων στο κανάλι. Αυτή τη στιγμή, η γορουτίνα θα κλειδωθεί στο κανάλι μέχρι να ολοκληρωθεί η ανταλλαγή.
  • Στο βήμα 3, η γορουτίνα στα δεξιά βάζει το χέρι της στο κανάλι, το οποίο προσομοιώνει τη λήψη δεδομένων από το κανάλι. Αυτή η γορουτίνα θα είναι επίσης κλειδωμένη στο κανάλι μέχρι να ολοκληρωθεί η ανταλλαγή.
  • Στα βήματα 4 και 5, λαμβάνει χώρα μια ανταλλαγή και τελικά, στο βήμα 6, και οι δύο γορουτίνες βγάζουν τα χέρια τους από το κανάλι, το οποίο προσομοιώνει την απελευθέρωση της κλειδωμένης γορουτίνας. Και οι δύο γορουτίνες μπορούν πλέον να κάνουν άλλα πράγματα.

Δημιουργήστε ένα κανάλι χωρίς buffer

make (chan Type)//等价于make (chan Type,0)
  • 1

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

Εισαγάγετε την περιγραφή της εικόνας εδώ

  • Το ch&lt;-i γράφει δεδομένα στο κανάλι Η κύρια κορουτίνα δεν θα την ανιχνεύσει.
  • Ωστόσο, το println εκτυπώνει δεδομένα μετά την ανάγνωση του σωλήνα, επομένως η ταχύτητα εκτύπωσης καθορίζεται από το σύστημα.

κανάλι προσωρινής αποθήκευσης

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

  • Στο βήμα 1, η γορουτίνα στα δεξιά λαμβάνει μια τιμή από το κανάλι.
  • Στο βήμα 2, η γκορουτίνα στα δεξιά ολοκληρώνει την ενέργεια λήψης της τιμής ανεξάρτητα, ενώ η γορουτίνα στα αριστερά στέλνει μια νέα τιμή στο κανάλι.
  • Στο βήμα 3, η γκορουτίνα στα αριστερά εξακολουθεί να στέλνει μια νέα τιμή στο κανάλι, ενώ η γορουτίνα στα δεξιά λαμβάνει μια άλλη τιμή από το κανάλι. Οι δύο λειτουργίες σε αυτό το βήμα δεν είναι ούτε συγχρονισμένες ούτε μπλοκάρουν η μία την άλλη.
  • Τέλος, στο βήμα 4, όλη η αποστολή και η λήψη ολοκληρώθηκαν και υπάρχουν ακόμα μερικές τιμές στο κανάλι και λίγος χώρος για αποθήκευση περισσότερων τιμών.

δημιουργώ

make (chan Type,capacity)
  • 1

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

ολοκληρώσει

Εισαγάγετε την περιγραφή της εικόνας εδώ

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

κλείσιμο καναλιού

Το κανάλι μπορεί να χρησιμοποιήσει το ok για να εντοπίσει εάν το κανάλι είναι ακόμα ανοιχτό, τα δεδομένα δεν θα διαβαστούν.

Εισαγάγετε την περιγραφή της εικόνας εδώ

  • num ,ok:=<-chΜπορεί να εντοπίσει εάν ένα κανάλι είναι κλειστό.

Ειδοποίηση

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

Κανάλι μονής κατεύθυνσης

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

var ch1 chan int //ch1双向
var ch2 chan<-float64 //ch2单向,只能用于写float64数据
var ch3 <-chan int  //ch3单向,只能用于读int数据
  • 1
  • 2
  • 3

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

Εισαγάγετε την περιγραφή της εικόνας εδώ

Χρησιμοποιήστε ένα μόνο κανάλι για να εφαρμόσετε το μοντέλο παραγωγού-καταναλωτή

Εισαγάγετε την περιγραφή της εικόνας εδώ