Увод у заједничку меморију у ЈаваСцрипту
Заједничка меморија је напредна карактеристика ЈаваСцрипт-а, да нити (истовремено извршени делови процеса) могу искористити. Дељење меморијских средстава нема проблема да проследи ажуриране податке између нити и све нити могу приступити и ажурирати исте податке у заједничкој меморији.
Зар то не звучи дивно? Па замало. У овом посту, видећемо како користити заједничку меморију у ЈаваСцрипту и како одлучити да ли је то оно што заиста желите.
Предности и недостаци заједничке меморије
Користимо веб воркерс до креирајте нити у ЈаваСцрипт-у. Веб Воркерс АПИ нам омогућава да креирамо радне нити које се могу користити извршите код у позадини тако да је главна нит слободна да настави са извршавањем, евентуално обрађујући УИ догађаје, осигуравајући да нема замрзавања корисничког интерфејса.
Воркер тхреадс изводити истовремено са главном нити и једни другима. Такво истовремено извршавање различитих делова задатка штеди време. Завршавате брже, али има и своје проблеме.
Осигурати да свака нит добија потребне ресурсе и комуницира међусобно на вријеме то је задатак сам по себи, гдје несрећа може резултирати изненађујућим исходом. Или ако једна нит мијења податке, а друга је чита истовремено, Шта мислите да ће друга нит видјети? Ажурирани или стари подаци?
Међутим, веб-радници нису тако лако зајебати. Током њихове комуникације путем порука, подаци које шаљу један другом су није оригинал, већ копија, што значи да не знају Објави исте податке. Они преносити копије података једни другима када је то потребно.
Али дијељење је брижно, а вишеструке нити би требале истовремено гледати исте податке и мијењати их. Тако, дељење забрана је велики не-не. Ово је место где СхаредАрраиБуффер
објект долази на слику. Пустиће нас делите бинарне податке између више нити.
Тхе СхаредАрраиБуффер
објекат
Уместо прослеђивања копија података између нити, ми копије СхаредАрраиБуффер
објекат. А СхаредАрраиБуффер
објекат показује на меморију у којој су подаци сачувани.
Дакле, чак и када су копије СхаредАрраиБуффер
се преносе између нити, они све ће и даље указивати на исту меморију где се чувају оригинални подаци. Нити, дакле, могу прегледајте и ажурирајте податке у истој меморији.
Веб воркерс без дељена меморија
Да бисмо видели како веб радник ради без дељене меморије, ми креирајте радну нит и проследите му неке податке.
Тхе индек.хтмл
датотека држи маин сцрипт унутра а као што можете да видите испод:
цонст в = нови радник ('воркер.јс'); вар н = 9; в.постМессаге (н);
Тхе воркер.јс
филе носи радни скрипт:
онмессаге = (е) => цонсоле.гроуп ('[радник]'); цонсоле.лог ('Подаци примљени из главне теме:% и', е.дата); цонсоле.гроупЕнд ();
Користећи горњи код добијамо следеће излаз у конзоли:
[радник] Подаци примљени из главне теме: 9
Моју претходну поруку можете прочитати на веб радницима ради потпуног објашњења горе наведених исјечака.
За сада, имајте на уму да су подаци послато назад и назад између нити помоћу постМессаге ()
метода. Подаци су на другу страну поруку
евент хандлер, као вредност догађаја података
својство.
Сада, ако ми промените податке да ли ће се приказати ажуриран на крају пријема? Хајде да видимо:
цонст в = нови радник ('воркер.јс'); вар н = 9; в.постМессаге (н); н = 1;
Као што се и очекивало подаци имају не је ажуриран:
[радник] Подаци примљени из главне теме: 9
Зашто би то уопште било? Његово само клон послан раднику из главног скрипта.
Веб воркерс са дељена меморија
Сада ћемо користити СхаредАрраиБуффер
објекат у истом примеру. Можемо створити ново СхаредАрраиБуффер
на пример помоћу нев
кључне речи. Конструктор узима један параметар; а вредност дужине у бајтовима, одређујући величину бафера.
цонст в = нови радник ('воркер.јс'); буфф = нев СхаредАрраиБуффер (1); вар арр = ново Инт8Арраи (буфф); / * подешавање података * / арр [0] = 9; / * слање бафера (копија) раднику * / в.постМессаге (буфф);
Приметите да а СхаредАрраиБуффер
објекат представља само дељено меморијско подручје. До погледајте и промените бинарне податке, треба да користимо одговарајућу структуру података (а ТипедАрраи
или а ДатаВиев
објект).
Ин тхе индек.хтмл
изнад, нови СхаредАрраиБуффер
је креиран, са само једном бајтном дужином. Онда, нови Инт8Арраи
, која је једна врста ТипедАрраи
објеката поставите податке на “9” у предвиђеном бајтном простору.
онмессаге = (е) => вар арр = нови Инт8Арраи (е.дата); цонсоле.гроуп ('[воркер]'); цонсоле.лог ('Подаци примљени из главне теме:% и', арр [0]); цонсоле.гроупЕнд ();
Инт8Арраи
користи се и код радника, до прегледајте податке у баферу.
Тхе очекивана вредност се појављује у конзоли из радничке нити, што је управо оно што смо хтјели:
[радник] Подаци примљени из главне теме: 9
Сада, хајде ажурирајте податке у главној нити да види да ли се промена одражава на радника.
цонст в = нев Воркер ('воркер.јс'), буфф = нев СхаредАрраиБуффер (1); вар арр = ново Инт8Арраи (буфф); / * подешавање података * / арр [0] = 9; / * слање бафера (копија) раднику * / в.постМессаге (буфф); / * промена података * / арр [0] = 1;
И, као што можете видети испод, ажурирање одражава се унутар радника!
[радник] Подаци примљени из главне теме: 1
Али, и код треба радити обрнуто: када се вредност у раднику прво промени такође треба да се ажурира када се штампа из главне нити.
У овом случају наш код изгледа овако:
онмессаге = (е) => вар арр = нови Инт8Арраи (е.дата); цонсоле.гроуп ('[воркер]'); цонсоле.лог ('Подаци примљени из главне теме:% и', арр [0]); цонсоле.гроупЕнд (); / * промена података * / арр [0] = 7; / * постављање на главни тхреад * / постМессаге (");
Тхе подаци се мијењају у раднику и један празна порука је постављена на главну нит сигнализира да су подаци у баферу промењени и да је спреман за излаз главне нити.
цонст в = нев Воркер ('воркер.јс'), буфф = нев СхаредАрраиБуффер (1); вар арр = ново Инт8Арраи (буфф); / * подешавање података * / арр [0] = 9; / * слање бафера (копија) раднику * / в.постМессаге (буфф); / * промена података * / арр [0] = 1; / * штампање података након што га је радник променио * / в.онмессаге = (е) => цонсоле.гроуп ('[маин]'); цонсоле.лог ('Ажурирани подаци примљени из радног низа:% и', арр [0]); цонсоле.гроупЕнд ();
И, ово такође функционише! Подаци у баферу су исти као подаци унутар радника.
[воркер] Подаци примљени из главне теме: 1 [маин] Ажурирани подаци примљени из радног низа: 7
Вредност појављује се ажурирано у оба случаја; и главна и радна нит прегледају и мењају исте податке.
Завршне речи
Као што сам већ споменуо, користећи заједничку меморију у ЈаваСцрипту није без мана. На програмерима је да осигурају да секвенца извршења се догађа како је предвиђено и не постоје двије нити које се натјечу да добију исте податке јер нитко не зна тко ће узети трофеј.
Ако сте више заинтересовани за заједничку меморију, погледајте документацију Атомицс
објекат. Тхе Атомицс објект може вам помоћи с неким од тешкоћа, смањењем непредвидиве природе читања / писања из заједничке меморије.