Ievads koplietojamā atmiņā JavaScript
Koplietotā atmiņa ir uzlabota JavaScript iezīme, ka pavedieni (vienlaicīgi izpildītas procesa daļas) var piesaistīt. Atmiņas līdzekļu koplietošana nav grūtības nodot atjauninātos datus starp pavedieniem un visi pavedieni var piekļūt un atjaunināt tos pašus datus koplietotajā atmiņā.
Vai tas nav skaisti? Nu, gandrīz. Šajā ziņojumā mēs redzēsim kā izmantot koplietojamo atmiņu JavaScript un kā izlemt, vai tas ir tas, ko jūs patiešām vēlaties darīt.
Kopīgās atmiņas priekšrocības un trūkumi
Mēs izmantojam tīmekļa darbinieki uz izveidot pavedienus JavaScript. Tīmekļa darbinieku API ļauj mums izveidot strādnieku pavedienus, kurus var izmantot izpildīt kodu fonā tā, lai galvenais pavediens varētu brīvi turpināt izpildi, iespējams, apstrādājot lietotāja interfeisa notikumus, nodrošinot, ka nav UI iesaldēšanas.
Darbinieku pavedieni darboties vienlaicīgi ar galveno pavedienu un viens otru. Šāda uzdevuma dažādu daļu vienlaicīga izpilde ir laika taupīšana. Jūs pabeidzat ātrāk, bet tai ir arī savas problēmas.
Pārliecinieties, ka katrs pavediens saņem nepieciešamos resursus un savlaicīgi sazinās savā starpā ir uzdevums pats par sevi, ja neveiksme var radīt pārsteidzošu rezultātu. Vai, ja viens pavediens maina datus, un vēl viens to lasa tajā pašā laikā, ko jūs domājat otrs pavediens? Atjauninātie vai vecie dati?
Tomēr tīmekļa darbinieki nav tik vienkārši, lai tos pieskrūvētu. Sakaru laikā, izmantojot ziņojumus, dati, ko tie sūta viens otram, ir nevis oriģināls, bet kopija, nozīmē, ka tie nav dalīties tos pašus datus. Viņi datu kopijas kad nepieciešams.
Taču koplietošana ir rūpīga, un vairākiem pavedieniem var būt nepieciešams apskatīt tos pašus datus vienlaicīgi un tos mainīt. Tātad, koplietošanas aizliegšana ir liels nē. Tas ir, ja SharedArrayBuffer
objekts nonāk attēlā. Tas mums ļaus koplietojiet bināros datus starp vairākiem pavedieniem.
The SharedArrayBuffer
objektu
Tā vietā, lai nodotu datu kopijas starp pavedieniem, mēs nodot kopijas SharedArrayBuffer
objektu. A SharedArrayBuffer
objektu norāda uz atmiņu, kurā dati tiek saglabāti.
Tātad, pat tad, ja kopijas SharedArrayBuffer
tie tiek nodoti starp pavedieniem, tie visi joprojām norādīs uz to pašu atmiņu kur sākotnējie dati tiek saglabāti. Tādējādi pavedieni var apskatīt un atjaunināt datus tajā pašā atmiņā.
Web darbinieki bez koplietojamo atmiņu
Lai redzētu, kā tīmekļa darbinieks darbojas, neizmantojot kopīgu atmiņu, mēs izveidot darba vītni un nodot dažus datus.
The index.html
failam ir galvenais skripts iekšpusē a atzīmējiet, kā jūs to redzat tālāk:
const w = jauns darbinieks ('worker.js'); var n = 9; w.postMessage (n);
The worker.js
failā ir darba skripts:
onmessage = (e) => console.group ('[darbinieks]); console.log ('Dati, kas saņemti no galvenajiem pavedieniem:% i', e.data); console.groupEnd ();
Izmantojot iepriekš minēto kodu, mēs iegūstam šādu izvade konsolē:
[darbinieks] Dati, kas saņemti no galvenajiem pavedieniem: 9
Jūs varat izlasīt iepriekšminēto amatu tīmekļa darbiniekos, lai iegūtu pilnīgu iepriekš minēto fragmentu skaidrojumu.
Tagad paturiet prātā, ka dati ir nosūtīts uz priekšu un atpakaļ starp pavedieniem izmantojot postMessage ()
metodi. Dati ir otrā pusē ziņu
notikumu apstrādātājs, kā notikuma vērtību datus
īpašums.
Tagad, ja mēs mainīt datus vai tas parādīsies atjauninājumā saņēmēja galā? Paskatīsimies:
const w = jauns darbinieks ('worker.js'); var n = 9; w.postMessage (n); n = 1;
Kā gaidīts, dati ir ne atjaunināts:
[darbinieks] Dati, kas saņemti no galvenajiem pavedieniem: 9
Kāpēc tas tomēr būtu? Tas ir tikai klons, kas nosūtīts darbiniekam no galvenā skripta.
Web darbinieki ar koplietojamo atmiņu
Tagad mēs izmantot SharedArrayBuffer
objektu tajā pašā piemērā. Mēs varam izveidot jaunu SharedArrayBuffer
piemēram, izmantojot jauns
atslēgvārdu. Konstruktors ņem vienu parametru; a garuma vērtība baitos, norādot bufera lielumu.
const w = jauns darbinieks ('worker.js'); buff = new SharedArrayBuffer (1); var arr = jauns Int8Array (bifeļāda); / * iestatījumu dati * / arr [0] = 9; / * bufera (kopijas) nosūtīšana darbiniekam * / w.postMessage (buff);
Ņemiet vērā, ka a SharedArrayBuffer
objektu ir tikai koplietojamā atmiņas zona. Uz redzēt un mainīt bināro datus, mums ir jāizmanto atbilstoša datu struktūra (a TypedArray
vai a DataView
objekts).
Iekš index.html
augšā, jauns SharedArrayBuffer
ir izveidots tikai ar vienu baitu garumu. Tad jauns Int8Array
, kas ir viena veida TypedArray
objektiem iestatiet datus “9” paredzētajā baitu telpā.
onmessage = (e) => var arr = jauns Int8Array (e.data); console.group (“[darbinieks]”); console.log ('Dati, kas saņemti no galvenā pavediena:% i', arr [0]); console.groupEnd ();
Int8Array
tiek izmantots arī darbiniekam skatīt datus buferī.
The paredzamā vērtība parādās konsolē no darbinieka pavediena, kas ir tieši tas, ko mēs vēlējāmies:
[darbinieks] Dati, kas saņemti no galvenajiem pavedieniem: 9
Tagad, pieņemsim atjaunināt datus galvenajā pavedienā lai redzētu, vai izmaiņas ir atspoguļotas darbiniekā.
const w = jauns darbinieks ('worker.js'), buff = jauns SharedArrayBuffer (1); var arr = jauns Int8Array (bifeļāda); / * iestatījumu dati * / arr [0] = 9; / * bufera (kopijas) nosūtīšana darbiniekam * / w.postMessage (buff); / * datu mainīšana * / arr [0] = 1;
Un, kā redzams zemāk, atjauninājums atspoguļo darba ņēmēja iekšienē!
[darbinieks] Dati, kas saņemti no galvenajiem pavedieniem: 1
Bet, kods arī jāstrādā otrādi: kad darba ņēmēja vērtība sākumā mainās arī jāatjaunina kad tas ir izdrukāts no galvenā pavediena.
Šādā gadījumā mūsu kods izskatās šādi:
onmessage = (e) => var arr = jauns Int8Array (e.data); console.group (“[darbinieks]”); console.log ('Dati, kas saņemti no galvenā pavediena:% i', arr [0]); console.groupEnd (); / * datu mainīšana * / arr [0] = 7; / * publicēšana galvenajā pavedienā * / postMessage (");
The dati tiek mainīti darbiniekā un tukšs ziņojums tiek ievietots galvenajā pavedienā signalizējot, ka buferī esošie dati ir mainīti un ir gatavs galvenajam pavedienam izvadīt.
const w = jauns darbinieks ('worker.js'), buff = jauns SharedArrayBuffer (1); var arr = jauns Int8Array (bifeļāda); / * iestatījumu dati * / arr [0] = 9; / * bufera (kopijas) nosūtīšana darbiniekam * / w.postMessage (buff); / * datu mainīšana * / arr [0] = 1; / * datu drukāšana pēc tam, kad darbinieks to ir mainījis * / w.onmessage = (e) => console.group ('[main]'); console.log ('Atjaunināti dati, kas saņemti no darbinieku pavediena:% i', arr [0]); console.groupEnd ();
Un tas arī darbojas! Bufera dati ir tādi paši kā darbinieka dati.
[darbinieks] Dati, kas saņemti no galvenajiem pavedieniem: 1 [galvenais] Atjaunināti dati, kas saņemti no strādnieka pavediena: 7
Vērtība abos gadījumos tiek atjaunināts; gan galvenie, gan strādnieku pavedieni skatās un maina tos pašus datus.
Nobeiguma vārdi
Kā jau iepriekš minēju, izmantojot koplietojamo atmiņu JavaScript nav bez trūkumiem. Tas ir atkarīgs no izstrādātājiem, lai nodrošinātu, ka izpildes secība notiek, kā paredzēts un neviens no diviem pavedieniem nav sacīkšu, lai iegūtu tādus pašus datus, jo neviens nezina, kas uzņems trofeju.
Ja jūs vēlaties vairāk dalīties atmiņā, apskatiet dokumentāciju Atomika
objektu. The Atomikas objekts var jums palīdzēt ar dažām grūtībām, samazinot neparedzamo lasīšanas / rakstīšanas raksturu no koplietojamās atmiņas.