Početna » šifriranje » Uvod u zajedničku memoriju u JavaScriptu

    Uvod u zajedničku memoriju u JavaScriptu

    Zajednička memorija je napredna značajka JavaScripta, da niti (istodobno izvršeni dijelovi procesa) mogu utjecati. Dijeljenje memorijskih sredstava nema problema s prosljeđivanjem ažuriranih podataka između niti i sve niti mogu pristupiti i ažurirati iste podatke u zajedničkoj memoriji.

    Zar to ne zvuči divno? Pa, gotovo. U ovom postu vidjet ćemo kako koristiti zajedničku memoriju u JavaScriptu i kako odlučiti je li to ono što stvarno želite učiniti.

    Prednosti i nedostaci zajedničke memorije

    Koristimo web radnici do stvorite niti u JavaScriptu. API API-ja za web-radnike omogućuje nam da stvorimo radne niti kojima se može koristiti izvršite kod u pozadini tako da je glavna nit slobodna da nastavi s izvršavanjem, moguće obrade UI događaja, osiguravajući da nema zamrzavanja korisničkog sučelja.

    Radni konci izvoditi istodobno s glavnim navojem i međusobno. Takvo istovremeno izvršavanje različitih dijelova zadatka štedi vrijeme. Završavate brže, ali ima i svoje probleme.

    Osigurati da svaka nit dobiva potrebne resurse i komunicira međusobno na vrijeme je zadatak sam po sebi, gdje nesreća može rezultirati iznenađujućim ishodom. Ili ako jedna nit mijenja podatke, a druga je čita u isto vrijeme, što mislite da će druga nit vidjeti? Ažurirani ili stari podaci?

    Međutim, web radnici nisu tako lako zajebati. Tijekom njihove komunikacije putem poruka, podaci koje šalju jedan drugome su ne original, nego kopija, što znači da ne znaju udio isti podaci. Oni međusobno prosljeđujte kopije podataka kada je potrebno.

    No dijeljenje je brižno, a više niti bi moglo istodobno gledati iste podatke i mijenjati ih. Tako, zabrana dijeljenja je velika ne-ne. Ovo je mjesto gdje SharedArrayBuffer objekt dolazi u sliku. Pustit će nas dijelite binarne podatke između više niti.

    SharedArrayBuffer objekt

    Umjesto prosljeđivanja kopija podataka između niti, mi kopije SharedArrayBuffer objekt. SharedArrayBuffer objekt pokazuje na memoriju u kojoj su podaci spremljeni.

    Dakle, čak i kada kopije SharedArrayBuffer su prošli između niti, oni sve će i dalje ukazivati ​​na istu memoriju gdje su izvorni podaci spremljeni. Niti, dakle, mogu pregledajte i ažurirajte podatke u istoj memoriji.

    Web radnici bez zajedničku memoriju

    Da bismo vidjeli kako web radnik radi bez zajedničke memorije, stvorite radnu nit i proslijediti mu neke podatke.

    index.html Datoteka sadrži glavna skripta unutar a kao što možete vidjeti u nastavku:

     const w = novi radnik ('worker.js'); var n = 9; w.postMessage (n); 

    worker.js datoteka nosi oznaku radnička skripta:

     onmessage = (e) => console.group ('[radnik]'); console.log ('Podaci primljeni iz glavne teme:% i', e.data); console.groupEnd ();  

    Koristeći gornji kod dobivamo sljedeće izlaz u konzoli:

     [radnik] Podaci primljeni iz glavne niti: 9 

    Moju gore navedenu poruku možete pročitati na web radnicima radi potpunog objašnjenja koda gore navedenih isječaka.

    Za sada, imajte na umu da su podaci poslane natrag i naprijed između niti koristiti postMessage () metoda. Podaci su na drugu stranu poruka rukovatelj događajima, kao vrijednost događaja podaci svojstvo.

    Sada, ako mi promijenite podatke će se prikazati ažuriran na kraju primitka? Da vidimo:

     const w = novi radnik ('worker.js'); var n = 9; w.postMessage (n); n = 1; 

    Kao što se i očekivalo podataka ima ne ažurirano:

     [radnik] Podaci primljeni iz glavne niti: 9 

    Zašto bi to uopće bilo? to je samo klon poslan radniku iz glavne skripte.

    Web radnici s zajedničku memoriju

    Sada ćemo koristiti SharedArrayBuffer objekt u istom primjeru. Možemo stvoriti novo SharedArrayBuffer na primjer koristiti novi ključna riječ. Konstruktor uzima jedan parametar; vrijednost duljine u bajtovima, određivanje veličine međuspremnika.

     const w = novi radnik ('worker.js'); buff = new SharedArrayBuffer (1); var arr = novi Int8Array (buff); / * postavljanje podataka * / arr [0] = 9; / * slanje bafera (kopija) radniku * / w.postMessage (buff); 

    Imajte na umu da a SharedArrayBuffer objekt predstavlja samo dijeljeno memorijsko područje. Do vidjeti i promijeniti binarne podatke, trebamo koristiti odgovarajuću strukturu podataka (a TypedArray ili a DataView objekt).

    U index.html iznad, novi SharedArrayBuffer je stvoren, s samo jednom bajtnom duljinom. Zatim, novi Int8Array, koja je jedna vrsta TypedArray objekata postavite podatke na “9” u predviđenom bajtnom prostoru.

     onmessage = (e) => var arr = novi Int8Array (e.data); console.group ( "[radnik]); console.log ('Podaci primljeni iz glavne teme:% i', arr [0]); console.groupEnd ();  

    Int8Array se također koristi u radniku, na prikaz podataka u međuspremniku.

    očekivana vrijednost pojavljuje se u konzoli iz radničke niti, što je upravo ono što smo htjeli:

     [radnik] Podaci primljeni iz glavne niti: 9 

    Sada, hajde ažurirati podatke u glavnoj niti kako bi se vidjelo da li se promjena odražava na radnika.

     const w = novi radnik ('worker.js'), buff = new SharedArrayBuffer (1); var arr = novi Int8Array (buff); / * postavljanje podataka * / arr [0] = 9; / * slanje bafera (kopija) radniku * / w.postMessage (buff); / * mijenjanje podataka * / arr [0] = 1;

    I, kao što možete vidjeti u nastavku, ažuriranje ne odražava unutar radnika!

     [radnik] Podaci primljeni iz glavne niti: 1 

    Ali, i kod treba raditi obrnuto: kada se vrijednost u radniku prvo mijenja također treba ažurirati kada se ispisuje iz glavne niti.

    U ovom slučaju naš kôd izgleda ovako:

     onmessage = (e) => var arr = novi Int8Array (e.data); console.group ( "[radnik]); console.log ('Podaci primljeni iz glavne teme:% i', arr [0]); console.groupEnd (); / * mijenjanje podataka * / arr [0] = 7; / * slanje na glavni thread * / postMessage ("); 

    podaci se mijenjaju u radniku i jedan prazna poruka je postavljena na glavnu nit signalizira da su podaci u međuspremniku promijenjeni i spremni su za izlaz glavne niti.

     const w = novi radnik ('worker.js'), buff = new SharedArrayBuffer (1); var arr = novi Int8Array (buff); / * postavljanje podataka * / arr [0] = 9; / * slanje bafera (kopija) radniku * / w.postMessage (buff); / * mijenjanje podataka * / arr [0] = 1; / * ispis podataka nakon što ga je radnik promijenio * / w.onmessage = (e) => console.group ('[main]'); console.log ('Ažurirani podaci primljeni iz radnog niza:% i', arr [0]); console.groupEnd ();  

    I to također djeluje! Podaci u međuspremniku su isti kao podaci unutar radnika.

     [radnik] Podaci primljeni iz glavne teme: 1 [glavni] Ažurirani podaci primljeni iz radničke niti: 7 

    Vrijednost pojavljuje se ažurirano u oba slučaja; i glavna i radna nit pregledavaju i mijenjaju iste podatke.

    Završne riječi

    Kao što sam već spomenuo, korištenje zajedničke memorije u JavaScriptu nije bez mana. To je do developera kako bi se osiguralo da slijed izvršenja se događa kako je predviđeno i niti dvije niti se ne natječu da dobiju iste podatke jer nitko ne zna tko će uzeti trofej.

    Ako ste zainteresirani za zajedničku memoriju više, pogledajte dokumentaciju Atomistika objekt. Atomics objekt može vam pomoći s nekim od teškoća, smanjenjem nepredvidive prirode čitanja / pisanja iz zajedničke memorije.