Inleiding tot gedeeld geheugen in JavaScript
Gedeeld geheugen is een geavanceerde functie van JavaScript, dat threads (gelijktijdig uitgevoerde delen van een proces) kunnen gebruiken. Het delen van het geheugen betekent dat u geen moeite hebt om bijgewerkte gegevens door te geven tussen threads en alle threads. U kunt dezelfde gegevens in het gedeelde geheugen openen en bijwerken.
Klinkt dat niet heerlijk? Nou bijna. In dit bericht zullen we zien hoe u gedeeld geheugen in JavaScript kunt gebruiken en hoe u kunt beslissen of dit is wat u echt wilt doen.
Voor- en nadelen van gedeeld geheugen
We gebruiken webmedewerkers om discussielijnen in JavaScript te maken . Met de Web Workers API kunnen we werkthreads maken die kunnen worden gebruikt om code op de achtergrond uit te voeren, zodat de hoofdthread vrij is om door te gaan met de uitvoering, mogelijk UI-events te verwerken en geen bevriezing van de gebruikersinterface te garanderen.
De werkthreads worden tegelijkertijd met de hoofdthread en met elkaar uitgevoerd . Een dergelijke gelijktijdige uitvoering van verschillende delen van een taak is tijdbesparend. Je eindigt sneller, maar het heeft ook zijn eigen reeks problemen.
Ervoor zorgen dat elke thread de nodige middelen krijgt en tijdig met elkaar communiceert, is een taak op zich, waarbij een incident kan resulteren in een verrassend resultaat. Of, als een thread bezig is met het wijzigen van gegevens en een andere leest het tegelijkertijd, wat denk je dat de andere thread zal zien? De bijgewerkte of de oude gegevens?
Webwerkers zijn echter niet zo gemakkelijk te verknoeien. Tijdens hun communicatie via het gebruik van berichten zijn de gegevens die ze elkaar sturen niet origineel, maar een kopie, wat betekent dat ze niet dezelfde gegevens delen. Ze geven indien nodig kopieën van gegevens aan elkaar door.
Maar delen is zorgzaam, en meerdere threads moeten mogelijk ook tegelijkertijd naar dezelfde gegevens kijken en deze wijzigen. Dus het verbieden van delen is een groot nee-nee . Dit is waar het SharedArrayBuffer
object in beeld komt. Hiermee kunnen we binaire gegevens delen tussen meerdere threads .
Het object SharedArrayBuffer
In plaats van de gegevenskopieën tussen threads door te geven, geven we kopieën van het SharedArrayBuffer
object door . Een SharedArrayBuffer
object SharedArrayBuffer
naar het geheugen waarin de gegevens worden opgeslagen .
Dus zelfs wanneer de kopieën van SharedArrayBuffer
worden doorgegeven tussen threads, zullen ze allemaal nog steeds naar hetzelfde geheugen verwijzen waar de originele gegevens zijn opgeslagen. De threads kunnen dus de gegevens in datzelfde geheugen bekijken en bijwerken .
Om te zien hoe een webwerker werkt zonder gedeeld geheugen te gebruiken, maken we een werkthread en geven we er enkele gegevens aan .
Het index.html
bestand bevat het hoofdscript binnen een tag, zoals je hieronder kunt zien:
const w = new Worker ('worker.js'); var n = 9; w.postMessage (n);
Het bestand worker.js
bevat het worker-script :
onmessage = (e) => {console.group ('[worker]'); console.log ('Gegevens ontvangen van hoofdthema:% i', e.data); console.groupEnd (); }
Met behulp van de bovenstaande code krijgen we de volgende uitvoer in de console :
[worker] Gegevens ontvangen van de hoofdthema: 9
Je kunt mijn voornoemde bericht op webwerkers lezen voor de volledige codeaanduiding van de bovenstaande fragmenten.
Houd er nu rekening mee dat gegevens tussen threads worden postMessage()
met de methode postMessage()
. De gegevens worden aan de andere kant ontvangen door de gebeurtenishandler message
, als de waarde van de eigenschap van de gebeurtenis.
Als we de gegevens wijzigen, wordt deze nu aan de ontvangende kant bijgewerkt? Laten we eens kijken:
const w = new Worker ('worker.js'); var n = 9; w.postMessage (n); n = 1;
Zoals verwacht, zijn de gegevens niet bijgewerkt :
[worker] Gegevens ontvangen van de hoofdthema: 9
Waarom zou het eigenlijk zijn? Het is gewoon een kloon die vanuit het hoofdscript naar de werknemer wordt gestuurd .
Webwerkers met gedeeld geheugen
Nu gebruiken we het SharedArrayBuffer
object in hetzelfde voorbeeld. We kunnen een nieuwe SharedArrayBuffer
instantie maken met behulp van het new
sleutelwoord . De constructor neemt één parameter; een lengtewaarde in bytes, waarbij de grootte van de buffer wordt opgegeven.
const w = new Worker ('worker.js'); buff = nieuwe SharedArrayBuffer (1); var arr = new Int8Array (buff); / * gegevens instellen * / arr [0] = 9; / * verzenden van de buffer (kopie) naar worker * / w.postMessage (buff);
Merk op dat een SharedArrayBuffer
object alleen een gedeeld geheugengebied vertegenwoordigt . Om de binaire gegevens te bekijken en te wijzigen, moeten we een geschikte gegevensstructuur gebruiken (een TypedArray
of een DataView
object).
In het bovenstaande bestand index.html
wordt een nieuwe SharedArrayBuffer
gemaakt met een lengte van slechts één byte. Vervolgens wordt een nieuwe Int8Array
, één type TypedArray
objecten, gebruikt om de gegevens in te stellen op "9" in de byte-ruimte .
onmessage = (e) => {var arr = new Int8Array (e.data); console.group ( '[werknemer]'); console.log ('Gegevens ontvangen van hoofdthema:% i', arr [0]); console.groupEnd (); }
Int8Array
wordt ook gebruikt in de worker om de gegevens in de buffer te bekijken .
De verwachte waarde verschijnt in de console van de werkthread, wat precies is wat we wilden:
[worker] Gegevens ontvangen van de hoofdthema: 9
Laten we nu de gegevens in de hoofdthread bijwerken om te zien of de wijziging wordt weerspiegeld in de worker.
const w = new Worker ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * gegevens instellen * / arr [0] = 9; / * verzenden van de buffer (kopie) naar worker * / w.postMessage (buff); / * wijzigen van de gegevens * / arr [0] = 1;
En, zoals u hieronder kunt zien, weerspiegelt de update in de werknemer !
[worker] Gegevens ontvangen van de hoofdthema: 1
Maar de code moet ook omgekeerd werken : wanneer de waarde in de worker in eerste instantie verandert, moet deze ook worden bijgewerkt wanneer deze in de hoofdthread wordt afgedrukt.
In dit geval ziet onze code er als volgt uit:
onmessage = (e) => {var arr = new Int8Array (e.data); console.group ( '[werknemer]'); console.log ('Gegevens ontvangen van hoofdthema:% i', arr [0]); console.groupEnd (); / * wijzigen van de gegevens * / arr [0] = 7; / * posten naar de hoofdthema * / postMessage (''); }
De gegevens worden in de werknemer gewijzigd en er wordt een leeg bericht geposteerd naar de hoofdthread die signaleert dat de gegevens in de buffer zijn gewijzigd en klaar is om de hoofdthread uit te voeren.
const w = new Worker ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * gegevens instellen * / arr [0] = 9; / * verzenden van de buffer (kopie) naar worker * / w.postMessage (buff); / * wijzigen van de gegevens * / arr [0] = 1; / * afdrukken van de gegevens nadat de medewerker deze heeft gewijzigd * / w.onmessage = (e) => {console.group ('[main]'); console.log ('bijgewerkte gegevens ontvangen van werkthread:% i', arr [0]); console.groupEnd (); }
En, dit werkt ook! De gegevens in de buffer zijn hetzelfde als de gegevens in de worker.
[worker] Gegevens ontvangen van de hoofdthema: 1 [hoofd] Bijgewerkte gegevens ontvangen van worker thread: 7
De waarde verschijnt in beide gevallen bijgewerkt ; zowel de hoofd- als werkthreads bekijken en wijzigen dezelfde gegevens.
Laatste woorden
Zoals ik eerder al zei, is het gebruik van gedeeld geheugen in JavaScript niet zonder nadelen . Het is aan ontwikkelaars om ervoor te zorgen dat de volgorde van uitvoering gebeurt zoals voorspeld en er geen twee threads aan het racen zijn om dezelfde gegevens te krijgen omdat niemand weet wie de trofee zal nemen.
Als u meer geïnteresseerd bent in gedeeld geheugen, bekijk dan de documentatie van het Atomics
object. Het Atomics-object kan u helpen met enkele van de ontberingen, door het onvoorspelbare karakter van lezen / schrijven uit het gedeelde geheugen te verminderen.
Tieners, Facebook en de toekomst van sociale media
"Teens leaving Facebook" is al een tijdje een favoriet onderwerp van de technische media . In 2010 had Mashable zelfs een artikel over tieners en 'Facebook-vermoeidheid' en het onderwerp is sindsdien niet ver verwijderd van de lippen van de tech-media. Meer recentelijk, in de tweede helft van 2013, kwam het onderwerp weer op de voorgrond, met nieuwsartikelen die verband hielden met deze vermeende tieneruittocht van Facebook op Business Insider, The Guardian, ABC News en bijna overal daar tussenin
20 meest creatieve ideeën voor huwelijksuitnodigingen ooit
Het seizoen is hier en je hebt waarschijnlijk een paar maanden geleden een huwelijksuitnodiging ontvangen. Er wordt veel werk besteed aan de voorbereiding van een huwelijksceremonie en terwijl sommige huwelijksuitnodigingen worden afgedrukt of met de hand worden geschreven, dragen ze een persoonlijk tintje