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

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

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

Συγχρονισμός στο Go

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

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

instagram viewer

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

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

Τρόπος χρήσης Goroutines για ταυτόχρονη εκτέλεση κώδικα

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

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

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

funcκύριος() {
πηγαίνω συνάρτηση 1() // Δημιουργία και εκτέλεση goroutine για τη συνάρτηση1
πηγαίνω συνάρτηση 2() // Δημιουργία και εκτέλεση goroutine για τη λειτουργία2

// ...
}

funcλειτουργία 1() {
// Κωδικός για τη συνάρτηση 1
}

funcλειτουργία 2() {
// Κωδικός για τη συνάρτηση 2
}

Όταν το πρόγραμμα καλεί συνάρτηση 1() και συνάρτηση 2() με την πηγαίνω λέξη-κλειδί, ο χρόνος εκτέλεσης Go εκτελεί τις λειτουργίες ταυτόχρονα ως γορουτίνες.

Ακολουθεί ένα παράδειγμα χρήσης μιας γορουτίνας που εκτυπώνει κείμενο στην κονσόλα:

πακέτο κύριος

εισαγωγή (
"fmt"
"χρόνος"
)

funcprintText() {
Για εγώ := 1; i <= 5; i++ {
fmt. Println("Εκτύπωση κειμένου", Εγώ)
χρόνος. Υπνος(1 * χρόνος. Δεύτερος)
}
}

funcκύριος() {
πηγαίνω printText() // Ξεκινήστε μια γορουτίνα για να εκτελέσετε τη συνάρτηση printText ταυτόχρονα

// Εκτελέστε άλλες εργασίες στην κύρια γορουτίνα
Για εγώ := 1; i <= 5; i++ {
fmt. Println("Εκτέλεση άλλων εργασιών", Εγώ)
χρόνος. Υπνος(500 * χρόνος. Μιλιδευτερόλεπτο)
}

// Περιμένετε να τελειώσει η γορουτίνα
χρόνος. Υπνος(6 * χρόνος. Δεύτερος)
}

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

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

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

Χρήση καναλιών για επικοινωνία και συγχρονισμό

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

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

Θα χρησιμοποιήσετε το χειριστή για αποστολή και λήψη δεδομένων μέσω καναλιών.

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

funcκύριος() {
// Δημιουργήστε ένα κανάλι χωρίς buffer τύπου string
ch := φτιαχνω, κανω(chanσειρά)

// Goroutine 1: Στέλνει ένα μήνυμα στο κανάλι
πηγαίνωfunc() {
ch "Γεια σου, Κανάλι!"
}()

// Goroutine 2: Λαμβάνει το μήνυμα από το κανάλι
msg := fmt. Println (msg) // Έξοδος: Γεια, Κανάλι!
}

Το κανάλι στο κύριος Η συνάρτηση είναι ένα κανάλι χωρίς προσωρινή αποθήκευση με όνομα κεφ δημιουργήθηκε με το φτιαχνω, κανω() λειτουργία. Η πρώτη γορουτίνα στέλνει το μήνυμα "Γεια σου, Κανάλι!" στο κανάλι χρησιμοποιώντας το τελεστής και η δεύτερη γορουτίνα λαμβάνει το μήνυμα από το κανάλι χρησιμοποιώντας τον ίδιο τελεστή. Τέλος, το κύριος Η λειτουργία εκτυπώνει το ληφθέν μήνυμα στην κονσόλα.

Μπορείτε να ορίσετε δακτυλογραφημένα κανάλια. Θα καθορίσετε τον τύπο καναλιού κατά τη δημιουργία. Ακολουθεί ένα παράδειγμα που δείχνει τη χρήση διαφορετικών τύπων καναλιών:

funcκύριος() {
// Κανάλι χωρίς buffer
κεφ1 := φτιαχνω, κανω(chanενθ)

// Κανάλι προσωρινής αποθήκευσης με χωρητικότητα 3
κεφ2 := φτιαχνω, κανω(chanσειρά, 3)

// Αποστολή και λήψη τιμών από κανάλια
κεφ1 42// Στείλτε μια τιμή στο ch1
value1 := // Λήψη τιμής από το ch1

ch2 "Γειά σου"// Στείλτε μια τιμή στο ch2
value2 := // Λήψη τιμής από το ch2
}

ο κύριος Η λειτουργία δημιουργεί δύο κανάλια: κεφ1 είναι ένα ακέραιο κανάλι χωρίς προσωρινή αποθήκευση, ενώ κεφ2 είναι ένα buffered string κανάλι με χωρητικότητα 3. Μπορείτε να στείλετε και να λάβετε τιμές προς και από αυτά τα κανάλια χρησιμοποιώντας το τελεστή (οι τιμές πρέπει να είναι του καθορισμένου τύπου).

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

funcκύριος() {
ch := φτιαχνω, κανω(chanbool)

πηγαίνωfunc() {
fmt. Println("Goroutine 1")
ch αληθής// Ολοκλήρωση σήματος
}()

πηγαίνωfunc() {
// Περιμένετε για το σήμα ολοκλήρωσης από το Goroutine 1
fmt. Println("Goroutine 2")
}()

// Περιμένετε για το σήμα ολοκλήρωσης από το Goroutine 2
fmt. Println("Κύρια γορουτίνα")
}

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

Μπορείτε να δημιουργήσετε εφαρμογές Ιστού στο Go With Gin

Μπορείτε να δημιουργήσετε εφαρμογές ιστού υψηλής απόδοσης στο Go with Gin, αξιοποιώντας παράλληλα τις λειτουργίες ταυτόχρονης χρήσης του Go.

Μπορείτε να χρησιμοποιήσετε το Gin για να χειριστείτε αποτελεσματικά τη δρομολόγηση HTTP και το ενδιάμεσο λογισμικό. Εκμεταλλευτείτε την ενσωματωμένη υποστήριξη ταυτόχρονης χρήσης του Go χρησιμοποιώντας γορουτίνες και κανάλια για εργασίες όπως ερωτήματα βάσης δεδομένων, κλήσεις API ή άλλες λειτουργίες αποκλεισμού.