Αρχική σελίδα » Κωδικοποίηση » Εισαγωγή στη Κοινόχρηστη μνήμη στο JavaScript

    Εισαγωγή στη Κοινόχρηστη μνήμη στο JavaScript

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

    Δεν ακούγεται υπέροχο; Λοιπόν, σχεδόν. Σε αυτή τη θέση, θα δούμε πώς να χρησιμοποιήσετε κοινή μνήμη στο JavaScript και πώς να αποφασίσετε αν αυτό είναι αυτό που πραγματικά θέλετε να κάνετε.

    Πλεονεκτήματα και μειονεκτήματα της κοινής μνήμης

    Χρησιμοποιούμε εργαζόμενοι στο διαδίκτυο προς το δημιουργήστε θέματα σε JavaScript. Το Εργαλείο API Web Workers μας επιτρέπει να δημιουργούμε θέματα εργασίας τα οποία μπορούν να χρησιμοποιηθούν εκτελέστε κώδικα στο παρασκήνιο έτσι ώστε το κύριο νήμα να είναι ελεύθερο να συνεχίσει την εκτέλεσή του, ενδεχομένως να επεξεργάζεται τα UI γεγονότα, εξασφαλίζοντας ότι δεν θα παγώσει το UI.

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

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

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

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

    ο SharedArrayBuffer αντικείμενο

    Αντί να περάσουμε τα αντίγραφα των δεδομένων μεταξύ των νημάτων, εμείς pass αντίγραφα του SharedArrayBuffer αντικείμενο. ΕΝΑ SharedArrayBuffer αντικείμενο δείχνει τη μνήμη όπου αποθηκεύονται τα δεδομένα.

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

    Εργαζόμενοι στο Web χωρίς κοινή μνήμη

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

    ο index.html αρχείο διατηρεί το κύριο σενάριο μέσα σε α ετικέτα, όπως μπορείτε να δείτε παρακάτω:

     const w = νέος εργαζόμενος ('worker.js'); var ν = 9; w.postMessage (n); 

    ο work.js αρχείο φέρει το εργατικό σενάριο:

     onmessage = (e) => console.group ('[εργαζόμενος')); console.log ('Δεδομένα που ελήφθησαν από το κύριο νήμα:% i', e.data); console.groupEnd ();  

    Χρησιμοποιώντας τον παραπάνω κώδικα, έχουμε τα ακόλουθα έξοδο στην κονσόλα:

     [εργαζόμενος] Τα δεδομένα που ελήφθησαν από το κύριο νήμα: 9 

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

    Προς το παρόν, λάβετε υπόψη ότι τα δεδομένα είναι που μεταδίδονται εμπρός και πίσω μεταξύ των νημάτων χρησιμοποιώντας το postMessage () μέθοδος. Τα δεδομένα είναι έλαβε από την άλλη πλευρά το μήνυμα χειριστής συμβάντων, ως αξία της εκδήλωσης δεδομένα ιδιοκτησία.

    Τώρα, αν εμείς να αλλάξετε τα δεδομένα θα εμφανιστεί ενημερωμένο στο τέλος λήψης; Ας δούμε:

     const w = νέος εργαζόμενος ('worker.js'); var ν = 9; w.postMessage (n); n = 1. 

    Όπως ήταν αναμενόμενο, το τα δεδομένα έχουν δεν ενημερώθηκε:

     [εργαζόμενος] Τα δεδομένα που ελήφθησαν από το κύριο νήμα: 9 

    Γιατί θα ήταν, ούτως ή άλλως; Του απλά ένας κλώνος που αποστέλλεται στον εργαζόμενο από το κύριο σενάριο.

    Εργαζόμενοι στο Web με κοινή μνήμη

    Τώρα, θα το κάνουμε Χρησιμοποιήστε το SharedArrayBuffer αντικείμενο στο ίδιο παράδειγμα. Μπορούμε να δημιουργήσουμε ένα νέο SharedArrayBuffer παράδειγμα από χρησιμοποιώντας το νέος λέξη-κλειδί. Ο κατασκευαστής παίρνει μια παράμετρο. ένα η τιμή μήκους σε bytes, προσδιορίζοντας το μέγεθος του buffer.

     const w = νέος εργαζόμενος ('worker.js'); buff = νέο SharedArrayBuffer (1); var arr = νέο Int8Array (buff); / * ρύθμιση δεδομένων * / arr [0] = 9; / * αποστολή του buffer (αντίγραφο) στον εργαζόμενο * / w.postMessage (buff); 

    Σημειώστε ότι a SharedArrayBuffer αντικείμενο αντιπροσωπεύει μόνο μια περιοχή κοινής μνήμης. Προς το δείτε και αλλάξτε τα δυαδικά δεδομένα, πρέπει να χρησιμοποιήσουμε μια κατάλληλη δομή δεδομένων (α TypedArray ή α DataView αντικείμενο).

    Στο index.html αρχείο παραπάνω, ένα νέο SharedArrayBuffer δημιουργείται, με μήκος μόνο ενός byte. Στη συνέχεια, ένα νέο Int8Array, που είναι ένας τύπος TypedArray αντικείμενα, χρησιμοποιείται για να ορίστε τα δεδομένα σε “9” στο παρεχόμενο διάστημα byte.

     onmessage = (e) => var arr = νέα Int8Array (e.data); console.group ('εργαζόμενος'); console.log ('Δεδομένα που ελήφθησαν από το κύριο νήμα:% i', arr [0]); console.groupEnd ();  

    Int8Array χρησιμοποιείται επίσης στον εργαζόμενο, για να προβάλετε τα δεδομένα στο buffer.

    ο η αναμενόμενη τιμή εμφανίζεται στην κονσόλα από το νήμα εργατών, το οποίο ακριβώς θέλαμε:

     [εργαζόμενος] Τα δεδομένα που ελήφθησαν από το κύριο νήμα: 9 

    Τώρα, ας είναι ενημερώστε τα δεδομένα στο κύριο νήμα για να δείτε αν η αλλαγή αντικατοπτρίζεται στον εργαζόμενο.

     const w = νέος εργαζόμενος ('worker.js'), buff = νέος SharedArrayBuffer (1); var arr = νέο Int8Array (buff); / * ρύθμιση δεδομένων * / arr [0] = 9; / * αποστολή του buffer (αντίγραφο) στον εργαζόμενο * / w.postMessage (buff); / * αλλαγή των δεδομένων * / arr [0] = 1;

    Και, όπως μπορείτε να δείτε παρακάτω, την ενημέρωση αντανακλά μέσα στον εργαζόμενο!

     [εργαζόμενος] Τα δεδομένα που ελήφθησαν από το κύριο νήμα: 1 

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

    Σε αυτήν την περίπτωση, ο κώδικας μας μοιάζει με αυτόν τον τρόπο:

     onmessage = (e) => var arr = νέα Int8Array (e.data); console.group ('εργαζόμενος'); console.log ('Δεδομένα που ελήφθησαν από το κύριο νήμα:% i', arr [0]); console.groupEnd (); / * αλλαγή των δεδομένων * / arr [0] = 7; / * η δημοσίευση στο κύριο νήμα * / postMessage ("); 

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

     const w = νέος εργαζόμενος ('worker.js'), buff = νέος SharedArrayBuffer (1); var arr = νέο Int8Array (buff); / * ρύθμιση δεδομένων * / arr [0] = 9; / * αποστολή του buffer (αντίγραφο) στον εργαζόμενο * / w.postMessage (buff); / * αλλαγή των δεδομένων * / arr [0] = 1; / * εκτύπωση των δεδομένων μετά την αλλαγή του εργαζόμενου * / w.onmessage = (e) => console.group ('[main]'); console.log ('Ενημερωμένα δεδομένα που ελήφθησαν από το νήμα των εργαζομένων:% i', arr [0]); console.groupEnd ();  

    Και αυτό λειτουργεί επίσης! Τα δεδομένα στο buffer είναι ίδια με τα δεδομένα μέσα στον εργαζόμενο.

     [εργαζόμενο] Δεδομένα που ελήφθησαν από το κύριο νήμα: 1 [main] Ενημερωμένα δεδομένα που ελήφθησαν από το νήμα των εργαζομένων: 7 

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

    Τελικές λέξεις

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

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