જાવાસ્ક્રિપ્ટમાં સાચું મલ્ટિથ્રેડિંગ અનલૉક કરો. આ વ્યાપક માર્ગદર્શિકા SharedArrayBuffer, Atomics, વેબ વર્કર્સ અને ઉચ્ચ-પ્રદર્શન વેબ એપ્લિકેશન્સ માટે સુરક્ષા જરૂરિયાતોને આવરી લે છે.
જાવાસ્ક્રિપ્ટ SharedArrayBuffer: વેબ પર કોન્કરન્ટ પ્રોગ્રામિંગમાં ઊંડાણપૂર્વકનો અભ્યાસ
દાયકાઓથી, જાવાસ્ક્રિપ્ટની સિંગલ-થ્રેડેડ પ્રકૃતિ તેની સરળતાનો સ્ત્રોત અને એક મહત્વપૂર્ણ પ્રદર્શન અવરોધ બંને રહી છે. ઇવેન્ટ લૂપ મોડેલ મોટાભાગના UI-સંચાલિત કાર્યો માટે સુંદર રીતે કામ કરે છે, પરંતુ જ્યારે ગણતરીની રીતે સઘન કામગીરીનો સામનો કરવો પડે છે ત્યારે તે સંઘર્ષ કરે છે. લાંબા સમય સુધી ચાલતી ગણતરીઓ બ્રાઉઝરને ફ્રીઝ કરી શકે છે, જે એક નિરાશાજનક વપરાશકર્તા અનુભવ બનાવે છે. જ્યારે વેબ વર્કર્સે સ્ક્રિપ્ટને બેકગ્રાઉન્ડમાં ચલાવવાની મંજૂરી આપીને આંશિક ઉકેલ પૂરો પાડ્યો, ત્યારે તેઓ તેમની પોતાની મોટી મર્યાદા સાથે આવ્યા: બિનકાર્યક્ષમ ડેટા કમ્યુનિકેશન.
SharedArrayBuffer
(SAB) દાખલ કરો, એક શક્તિશાળી સુવિધા જે વેબ પર થ્રેડો વચ્ચે સાચું, નિમ્ન-સ્તરનું મેમરી શેરિંગ રજૂ કરીને મૂળભૂત રીતે રમતને બદલી નાખે છે. Atomics
ઓબ્જેક્ટ સાથે જોડી બનાવીને, SAB સીધા બ્રાઉઝરમાં ઉચ્ચ-પ્રદર્શન, કોન્કરન્ટ એપ્લિકેશન્સના નવા યુગને ખોલે છે. જો કે, મહાન શક્તિ સાથે મોટી જવાબદારી અને જટિલતા આવે છે.
આ માર્ગદર્શિકા તમને જાવાસ્ક્રિપ્ટમાં કોન્કરન્ટ પ્રોગ્રામિંગની દુનિયામાં ઊંડાણપૂર્વક લઈ જશે. અમે અન્વેષણ કરીશું કે આપણને તેની શા માટે જરૂર છે, SharedArrayBuffer
અને Atomics
કેવી રીતે કામ કરે છે, તમારે જે નિર્ણાયક સુરક્ષા બાબતોને સંબોધિત કરવી આવશ્યક છે, અને તમને પ્રારંભ કરવા માટે વ્યવહારુ ઉદાહરણો.
ધ ઓલ્ડ વર્લ્ડ: જાવાસ્ક્રિપ્ટનું સિંગલ-થ્રેડેડ મોડેલ અને તેની મર્યાદાઓ
આપણે ઉકેલની પ્રશંસા કરી શકીએ તે પહેલાં, આપણે સમસ્યાને સંપૂર્ણપણે સમજવી જોઈએ. બ્રાઉઝરમાં જાવાસ્ક્રિપ્ટ એક્ઝેક્યુશન પરંપરાગત રીતે એક જ થ્રેડ પર થાય છે, જેને ઘણીવાર "મુખ્ય થ્રેડ" અથવા "UI થ્રેડ" કહેવામાં આવે છે.
ધ ઇવેન્ટ લૂપ
મુખ્ય થ્રેડ બધી બાબતો માટે જવાબદાર છે: તમારો જાવાસ્ક્રિપ્ટ કોડ એક્ઝેક્યુટ કરવો, પેજ રેન્ડર કરવું, વપરાશકર્તાની ક્રિયાપ્રતિક્રિયાઓ (જેમ કે ક્લિક્સ અને સ્ક્રોલ્સ) નો પ્રતિસાદ આપવો, અને CSS એનિમેશન ચલાવવું. તે આ કાર્યોને ઇવેન્ટ લૂપનો ઉપયોગ કરીને સંચાલિત કરે છે, જે સતત સંદેશાઓ (કાર્યો) ની કતાર પર પ્રક્રિયા કરે છે. જો કોઈ કાર્ય પૂર્ણ થવામાં લાંબો સમય લે છે, તો તે આખી કતારને બ્લોક કરે છે. બીજું કંઈ થઈ શકતું નથી—UI ફ્રીઝ થઈ જાય છે, એનિમેશન અટકી જાય છે, અને પેજ પ્રતિભાવવિહીન બની જાય છે.
વેબ વર્કર્સ: સાચી દિશામાં એક પગલું
આ સમસ્યાને ઘટાડવા માટે વેબ વર્કર્સ રજૂ કરવામાં આવ્યા હતા. વેબ વર્કર અનિવાર્યપણે એક અલગ બેકગ્રાઉન્ડ થ્રેડ પર ચાલતી સ્ક્રિપ્ટ છે. તમે મુખ્ય થ્રેડને યુઝર ઇન્ટરફેસ હેન્ડલ કરવા માટે મુક્ત રાખીને, વર્કરને ભારે ગણતરીઓ ઑફલોડ કરી શકો છો.
મુખ્ય થ્રેડ અને વર્કર વચ્ચે સંચાર postMessage()
API દ્વારા થાય છે. જ્યારે તમે ડેટા મોકલો છો, ત્યારે તે સ્ટ્રક્ચર્ડ ક્લોન એલ્ગોરિધમ દ્વારા સંચાલિત થાય છે. આનો અર્થ એ છે કે ડેટા સિરિયલાઇઝ્ડ, કોપી અને પછી વર્કરના સંદર્ભમાં ડિસિરિયલાઇઝ્ડ થાય છે. જ્યારે અસરકારક છે, આ પ્રક્રિયામાં મોટા ડેટાસેટ્સ માટે નોંધપાત્ર ગેરફાયદા છે:
- પ્રદર્શન ઓવરહેડ: થ્રેડો વચ્ચે મેગાબાઇટ્સ અથવા ગીગાબાઇટ્સ ડેટાની નકલ કરવી ધીમી અને CPU-સઘન છે.
- મેમરીનો વપરાશ: તે મેમરીમાં ડેટાની ડુપ્લિકેટ બનાવે છે, જે મેમરી-પ્રતિબંધિત ઉપકરણો માટે એક મોટી સમસ્યા હોઈ શકે છે.
બ્રાઉઝરમાં એક વિડિઓ એડિટરની કલ્પના કરો. પ્રોસેસિંગ માટે સેકન્ડમાં 60 વખત વર્કરને આખી વિડિઓ ફ્રેમ (જે ઘણા મેગાબાઇટ્સ હોઈ શકે છે) પાછી મોકલવી તે પ્રતિબંધાત્મક રીતે ખર્ચાળ હશે. આ તે જ સમસ્યા છે જેને હલ કરવા માટે SharedArrayBuffer
ડિઝાઇન કરવામાં આવી હતી.
ધ ગેમ-ચેન્જર: SharedArrayBuffer
નો પરિચય
SharedArrayBuffer
એ ArrayBuffer
જેવું જ, એક નિશ્ચિત-લંબાઈનું રો બાઈનરી ડેટા બફર છે. નિર્ણાયક તફાવત એ છે કે SharedArrayBuffer
ને ઘણા થ્રેડો (દા.ત., મુખ્ય થ્રેડ અને એક અથવા વધુ વેબ વર્કર્સ) વચ્ચે શેર કરી શકાય છે. જ્યારે તમે postMessage()
નો ઉપયોગ કરીને SharedArrayBuffer
"મોકલો" છો, ત્યારે તમે કોપી મોકલી રહ્યા નથી; તમે મેમરીના તે જ બ્લોકનો સંદર્ભ મોકલી રહ્યા છો.
આનો અર્થ એ છે કે એક થ્રેડ દ્વારા બફરના ડેટામાં કરવામાં આવેલા કોઈપણ ફેરફારો અન્ય તમામ થ્રેડો માટે તરત જ દૃશ્યમાન થાય છે જેમની પાસે તેનો સંદર્ભ છે. આ ખર્ચાળ કોપી-અને-સિરિયલાઇઝ સ્ટેપને દૂર કરે છે, જે લગભગ-તાત્કાલિક ડેટા શેરિંગને સક્ષમ કરે છે.
તેને આ રીતે વિચારો:
postMessage()
સાથે વેબ વર્કર્સ: આ બે સહકર્મીઓ દ્વારા દસ્તાવેજ પર કોપી ઇમેઇલ કરીને કામ કરવા જેવું છે. દરેક ફેરફાર માટે આખી નવી કોપી મોકલવી જરૂરી છે.SharedArrayBuffer
સાથે વેબ વર્કર્સ: આ બે સહકર્મીઓ દ્વારા શેર્ડ ઓનલાઈન એડિટર (જેમ કે Google Docs) માં તે જ દસ્તાવેજ પર કામ કરવા જેવું છે. ફેરફારો બંનેને વાસ્તવિક-સમયમાં દેખાય છે.
શેર્ડ મેમરીનો ભય: રેસ કન્ડિશન્સ
તાત્કાલિક મેમરી શેરિંગ શક્તિશાળી છે, પરંતુ તે કોન્કરન્ટ પ્રોગ્રામિંગની દુનિયામાંથી એક ક્લાસિક સમસ્યા પણ રજૂ કરે છે: રેસ કન્ડિશન્સ.
રેસ કન્ડિશન ત્યારે થાય છે જ્યારે બહુવિધ થ્રેડો એક જ સમયે સમાન શેર્ડ ડેટાને ઍક્સેસ અને સંશોધિત કરવાનો પ્રયાસ કરે છે, અને અંતિમ પરિણામ તેઓ જે અણધાર્યા ક્રમમાં એક્ઝેક્યુટ થાય છે તેના પર આધાર રાખે છે. SharedArrayBuffer
માં સંગ્રહિત એક સરળ કાઉન્ટરનો વિચાર કરો. મુખ્ય થ્રેડ અને વર્કર બંને તેને વધારવા માંગે છે.
- થ્રેડ A વર્તમાન મૂલ્ય વાંચે છે, જે 5 છે.
- થ્રેડ A નવું મૂલ્ય લખી શકે તે પહેલાં, ઓપરેટિંગ સિસ્ટમ તેને થોભાવે છે અને થ્રેડ B પર સ્વિચ કરે છે.
- થ્રેડ B વર્તમાન મૂલ્ય વાંચે છે, જે હજુ પણ 5 છે.
- થ્રેડ B નવા મૂલ્ય (6) ની ગણતરી કરે છે અને તેને મેમરીમાં પાછું લખે છે.
- સિસ્ટમ થ્રેડ A પર પાછી સ્વિચ કરે છે. તેને ખબર નથી કે થ્રેડ B એ કંઈ કર્યું છે. તે જ્યાંથી અટક્યું હતું ત્યાંથી ફરી શરૂ થાય છે, તેના નવા મૂલ્ય (5 + 1 = 6) ની ગણતરી કરે છે અને 6 ને મેમરીમાં પાછું લખે છે.
ભલે કાઉન્ટર બે વાર વધારવામાં આવ્યું હતું, અંતિમ મૂલ્ય 6 છે, 7 નથી. ઓપરેશન્સ એટોમિક નહોતા—તેઓ વિક્ષેપિત કરી શકાતા હતા, જેના કારણે ડેટા ખોવાઈ ગયો. આ જ કારણ છે કે તમે SharedArrayBuffer
નો ઉપયોગ તેના નિર્ણાયક ભાગીદાર વિના કરી શકતા નથી: Atomics
ઓબ્જેક્ટ.
શેર્ડ મેમરીનો રક્ષક: ધ Atomics
ઓબ્જેક્ટ
Atomics
ઓબ્જેક્ટ SharedArrayBuffer
ઓબ્જેક્ટ્સ પર એટોમિક ઓપરેશન્સ કરવા માટે સ્ટેટિક પદ્ધતિઓનો સમૂહ પ્રદાન કરે છે. એટોમિક ઓપરેશન કોઈપણ અન્ય ઓપરેશન દ્વારા વિક્ષેપિત થયા વિના સંપૂર્ણ રીતે કરવામાં આવે તેની ખાતરી આપવામાં આવે છે. તે કાં તો સંપૂર્ણપણે થાય છે અથવા બિલકુલ નહીં.
Atomics
નો ઉપયોગ કરવાથી એ સુનિશ્ચિત કરીને રેસ કન્ડિશન્સ અટકાવવામાં આવે છે કે શેર્ડ મેમરી પર રીડ-મોડિફાય-રાઇટ ઓપરેશન્સ સુરક્ષિત રીતે કરવામાં આવે છે.
મુખ્ય Atomics
પદ્ધતિઓ
ચાલો Atomics
દ્વારા પૂરી પાડવામાં આવતી કેટલીક સૌથી મહત્વપૂર્ણ પદ્ધતિઓ જોઈએ.
Atomics.load(typedArray, index)
: આપેલ ઇન્ડેક્સ પરના મૂલ્યને એટોમિકલી વાંચે છે અને તેને પરત કરે છે. આ સુનિશ્ચિત કરે છે કે તમે સંપૂર્ણ, બિન-ભ્રષ્ટ મૂલ્ય વાંચી રહ્યા છો.Atomics.store(typedArray, index, value)
: આપેલ ઇન્ડેક્સ પર એક મૂલ્યને એટોમિકલી સંગ્રહિત કરે છે અને તે મૂલ્ય પરત કરે છે. આ સુનિશ્ચિત કરે છે કે લખવાની કામગીરીમાં વિક્ષેપ ન પડે.Atomics.add(typedArray, index, value)
: આપેલ ઇન્ડેક્સ પરના મૂલ્યમાં એટોમિકલી એક મૂલ્ય ઉમેરે છે. તે તે સ્થાન પરનું મૂળ મૂલ્ય પરત કરે છે. આx += value
નું એટોમિક સમકક્ષ છે.Atomics.sub(typedArray, index, value)
: આપેલ ઇન્ડેક્સ પરના મૂલ્યમાંથી એટોમિકલી એક મૂલ્ય બાદ કરે છે.Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)
: આ એક શક્તિશાળી શરતી લખવાની ક્રિયા છે. તે તપાસે છે કેindex
પરનું મૂલ્યexpectedValue
ની બરાબર છે કે નહીં. જો એમ હોય, તો તે તેનેreplacementValue
સાથે બદલે છે અને મૂળexpectedValue
પરત કરે છે. જો નહીં, તો તે કંઈ કરતું નથી અને વર્તમાન મૂલ્ય પરત કરે છે. આ તાળાઓ જેવા વધુ જટિલ સિંક્રોનાઇઝેશન પ્રિમિટિવ્સના અમલીકરણ માટે એક મૂળભૂત બિલ્ડિંગ બ્લોક છે.
સિંક્રોનાઇઝેશન: સરળ કામગીરીઓથી આગળ
ક્યારેક તમારે માત્ર સુરક્ષિત વાંચન અને લખવા કરતાં વધુની જરૂર હોય છે. તમારે થ્રેડોને એકબીજા સાથે સંકલન અને રાહ જોવાની જરૂર છે. એક સામાન્ય એન્ટિ-પેટર્ન "બિઝી-વેઇટિંગ" છે, જ્યાં એક થ્રેડ ચુસ્ત લૂપમાં બેસે છે, સતત ફેરફાર માટે મેમરી સ્થાન તપાસે છે. આ CPU સાયકલ્સનો બગાડ કરે છે અને બેટરી લાઇફ ઘટાડે છે.
Atomics
wait()
અને notify()
સાથે વધુ કાર્યક્ષમ ઉકેલ પૂરો પાડે છે.
Atomics.wait(typedArray, index, value, timeout)
: આ એક થ્રેડને સૂઈ જવાનું કહે છે. તે તપાસે છે કેindex
પરનું મૂલ્ય હજુ પણvalue
છે કે નહીં. જો એમ હોય, તો થ્રેડ સૂઈ જાય છે જ્યાં સુધી તેનેAtomics.notify()
દ્વારા જગાડવામાં ન આવે અથવા વૈકલ્પિકtimeout
(મિલિસેકન્ડમાં) પહોંચી ન જાય. જોindex
પરનું મૂલ્ય પહેલેથી જ બદલાઈ ગયું હોય, તો તે તરત જ પરત આવે છે. આ અતિ કાર્યક્ષમ છે કારણ કે સૂતો થ્રેડ લગભગ કોઈ CPU સંસાધનોનો ઉપયોગ કરતો નથી.Atomics.notify(typedArray, index, count)
: આનો ઉપયોગAtomics.wait()
દ્વારા ચોક્કસ મેમરી સ્થાન પર સૂઈ રહેલા થ્રેડોને જગાડવા માટે થાય છે. તે વધુમાં વધુcount
રાહ જોતા થ્રેડોને જગાડશે (અથવા જોcount
પ્રદાન ન કરવામાં આવ્યું હોય અથવાInfinity
હોય તો તે બધાને).
બધું એકસાથે મૂકવું: એક વ્યવહારુ માર્ગદર્શિકા
હવે જ્યારે આપણે સિદ્ધાંત સમજી ગયા છીએ, ચાલો SharedArrayBuffer
નો ઉપયોગ કરીને ઉકેલના અમલીકરણના પગલાંઓમાંથી પસાર થઈએ.
પગલું 1: સુરક્ષાની પૂર્વશરત - ક્રોસ-ઓરિજિન આઇસોલેશન
આ વિકાસકર્તાઓ માટે સૌથી સામાન્ય અવરોધ છે. સુરક્ષા કારણોસર, SharedArrayBuffer
ફક્ત એવા પૃષ્ઠોમાં જ ઉપલબ્ધ છે જે ક્રોસ-ઓરિજિન આઇસોલેટેડ સ્થિતિમાં છે. આ સ્પેક્ટર જેવી સ્પેક્યુલેટિવ એક્ઝેક્યુશન નબળાઈઓને ઘટાડવા માટે એક સુરક્ષા માપદંડ છે, જે સંભવિતપણે ઓરિજિન વચ્ચે ડેટા લીક કરવા માટે ઉચ્ચ-રીઝોલ્યુશન ટાઈમર (શેર્ડ મેમરી દ્વારા શક્ય બનેલ) નો ઉપયોગ કરી શકે છે.
ક્રોસ-ઓરિજિન આઇસોલેશનને સક્ષમ કરવા માટે, તમારે તમારા વેબ સર્વરને તમારા મુખ્ય દસ્તાવેજ માટે બે વિશિષ્ટ HTTP હેડરો મોકલવા માટે ગોઠવવું આવશ્યક છે:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
(COOP): તમારા દસ્તાવેજના બ્રાઉઝિંગ સંદર્ભને અન્ય દસ્તાવેજોથી અલગ પાડે છે, તેમને તમારી વિંડો ઓબ્જેક્ટ સાથે સીધી રીતે ક્રિયાપ્રતિક્રિયા કરવાથી અટકાવે છે.Cross-Origin-Embedder-Policy: require-corp
(COEP): જરૂરી છે કે તમારા પેજ દ્વારા લોડ થયેલ તમામ સબ-રિસોર્સ (જેમ કે છબીઓ, સ્ક્રિપ્ટો, અને iframes) કાં તો સમાન ઓરિજિનના હોવા જોઈએ અથવાCross-Origin-Resource-Policy
હેડર અથવા CORS સાથે સ્પષ્ટપણે ક્રોસ-ઓરિજિન લોડ કરવા યોગ્ય તરીકે ચિહ્નિત થયેલ હોવા જોઈએ.
આને સેટ કરવું પડકારજનક હોઈ શકે છે, ખાસ કરીને જો તમે તૃતીય-પક્ષ સ્ક્રિપ્ટો અથવા સંસાધનો પર આધાર રાખતા હોવ જે જરૂરી હેડરો પ્રદાન કરતા નથી. તમારા સર્વરને ગોઠવ્યા પછી, તમે બ્રાઉઝરના કન્સોલમાં self.crossOriginIsolated
પ્રોપર્ટી તપાસીને તમારું પેજ આઇસોલેટેડ છે કે નહીં તે ચકાસી શકો છો. તે true
હોવું આવશ્યક છે.
પગલું 2: બફર બનાવવું અને શેર કરવું
તમારી મુખ્ય સ્ક્રિપ્ટમાં, તમે SharedArrayBuffer
અને Int32Array
જેવા TypedArray
નો ઉપયોગ કરીને તેના પર એક "વ્યૂ" બનાવો છો.
main.js:
// પ્રથમ ક્રોસ-ઓરિજિન આઇસોલેશન માટે તપાસો!
if (!self.crossOriginIsolated) {
console.error("આ પેજ ક્રોસ-ઓરિજિન આઇસોલેટેડ નથી. SharedArrayBuffer ઉપલબ્ધ રહેશે નહીં.");
} else {
// એક 32-બીટ પૂર્ણાંક માટે શેર્ડ બફર બનાવો.
const buffer = new SharedArrayBuffer(4);
// બફર પર વ્યૂ બનાવો. બધી એટોમિક કામગીરીઓ વ્યૂ પર થાય છે.
const int32Array = new Int32Array(buffer);
// ઇન્ડેક્સ 0 પર મૂલ્યને પ્રારંભ કરો.
int32Array[0] = 0;
// નવો વર્કર બનાવો.
const worker = new Worker('worker.js');
// વર્કરને શેર્ડ બફર મોકલો. આ એક રેફરન્સ ટ્રાન્સફર છે, કોપી નથી.
worker.postMessage({ buffer });
// વર્કરમાંથી આવતા સંદેશાઓ સાંભળો.
worker.onmessage = (event) => {
console.log(`વર્કરે પૂર્ણતાની જાણ કરી. અંતિમ મૂલ્ય: ${Atomics.load(int32Array, 0)}`);
};
}
પગલું 3: વર્કરમાં એટોમિક ઓપરેશન્સ કરવું
વર્કર બફર મેળવે છે અને હવે તેના પર એટોમિક ઓપરેશન્સ કરી શકે છે.
worker.js:
self.onmessage = (event) => {
const { buffer } = event.data;
const int32Array = new Int32Array(buffer);
console.log("વર્કરે શેર્ડ બફર મેળવ્યું.");
// ચાલો કેટલીક એટોમિક કામગીરીઓ કરીએ.
for (let i = 0; i < 1000000; i++) {
// શેર્ડ મૂલ્યને સુરક્ષિત રીતે વધારો.
Atomics.add(int32Array, 0, 1);
}
console.log("વર્કરે વધારો કરવાનું પૂર્ણ કર્યું.");
// મુખ્ય થ્રેડને સંકેત આપો કે અમે પૂર્ણ કરી લીધું છે.
self.postMessage({ done: true });
};
પગલું 4: વધુ અદ્યતન ઉદાહરણ - સિંક્રોનાઇઝેશન સાથે પેરેલલ સમમેશન
ચાલો એક વધુ વાસ્તવિક સમસ્યાનો સામનો કરીએ: બહુવિધ વર્કર્સનો ઉપયોગ કરીને ખૂબ મોટી સંખ્યાઓની એરેનો સરવાળો કરવો. અમે કાર્યક્ષમ સિંક્રોનાઇઝેશન માટે Atomics.wait()
અને Atomics.notify()
નો ઉપયોગ કરીશું.
આપણા શેર્ડ બફરમાં ત્રણ ભાગો હશે:
- ઇન્ડેક્સ 0: એક સ્ટેટસ ફ્લેગ (0 = પ્રોસેસિંગ, 1 = પૂર્ણ).
- ઇન્ડેક્સ 1: કેટલા વર્કર્સ પૂર્ણ થયા છે તે માટેનું કાઉન્ટર.
- ઇન્ડેક્સ 2: અંતિમ સરવાળો.
main.js:
if (self.crossOriginIsolated) {
const NUM_WORKERS = 4;
const DATA_SIZE = 10_000_000;
// [સ્ટેટસ, વર્કર્સ_ફિનિશ્ડ, રિઝલ્ટ_લો, રિઝલ્ટ_હાઈ]
// મોટા સરવાળા માટે ઓવરફ્લો ટાળવા માટે અમે પરિણામ માટે બે 32-બીટ પૂર્ણાંકોનો ઉપયોગ કરીએ છીએ.
const sharedBuffer = new SharedArrayBuffer(4 * 4); // 4 પૂર્ણાંકો
const sharedArray = new Int32Array(sharedBuffer);
// પ્રક્રિયા કરવા માટે કેટલાક રેન્ડમ ડેટા જનરેટ કરો
const data = new Uint8Array(DATA_SIZE);
for (let i = 0; i < DATA_SIZE; i++) {
data[i] = Math.floor(Math.random() * 10);
}
const chunkSize = Math.ceil(DATA_SIZE / NUM_WORKERS);
for (let i = 0; i < NUM_WORKERS; i++) {
const worker = new Worker('sum_worker.js');
const start = i * chunkSize;
const end = Math.min(start + chunkSize, DATA_SIZE);
// વર્કરના ડેટાના ચંક માટે નોન-શેર્ડ વ્યૂ બનાવો
const dataChunk = data.subarray(start, end);
worker.postMessage({
sharedBuffer,
dataChunk // આ કોપી થાય છે
});
}
console.log('મુખ્ય થ્રેડ હવે વર્કર્સ પૂર્ણ થવાની રાહ જોઈ રહ્યું છે...');
// ઇન્ડેક્સ 0 પરના સ્ટેટસ ફ્લેગને 1 થવાની રાહ જુઓ
// આ while લૂપ કરતાં ઘણું સારું છે!
Atomics.wait(sharedArray, 0, 0); // જો sharedArray[0] 0 હોય તો રાહ જુઓ
console.log('મુખ્ય થ્રેડ જાગી ગયું!');
const finalSum = Atomics.load(sharedArray, 2);
console.log(`અંતિમ પેરેલલ સરવાળો છે: ${finalSum}`);
} else {
console.error('પેજ ક્રોસ-ઓરિજિન આઇસોલેટેડ નથી.');
}
sum_worker.js:
self.onmessage = ({ data }) => {
const { sharedBuffer, dataChunk } = data;
const sharedArray = new Int32Array(sharedBuffer);
// આ વર્કરના ચંક માટે સરવાળો ગણો
let localSum = 0;
for (let i = 0; i < dataChunk.length; i++) {
localSum += dataChunk[i];
}
// સ્થાનિક સરવાળાને શેર્ડ ટોટલમાં એટોમિકલી ઉમેરો
Atomics.add(sharedArray, 2, localSum);
// 'વર્કર્સ ફિનિશ્ડ' કાઉન્ટરને એટોમિકલી વધારો
const finishedCount = Atomics.add(sharedArray, 1, 1) + 1;
// જો આ સમાપ્ત થનારો છેલ્લો વર્કર છે...
const NUM_WORKERS = 4; // વાસ્તવિક એપ્લિકેશનમાં પસાર કરવું જોઈએ
if (finishedCount === NUM_WORKERS) {
console.log('છેલ્લો વર્કર સમાપ્ત થયો. મુખ્ય થ્રેડને સૂચિત કરી રહ્યું છે.');
// 1. સ્ટેટસ ફ્લેગને 1 (પૂર્ણ) પર સેટ કરો
Atomics.store(sharedArray, 0, 1);
// 2. મુખ્ય થ્રેડને સૂચિત કરો, જે ઇન્ડેક્સ 0 પર રાહ જોઈ રહ્યું છે
Atomics.notify(sharedArray, 0, 1);
}
};
વાસ્તવિક-દુનિયાના ઉપયોગના કેસો અને એપ્લિકેશન્સ
આ શક્તિશાળી પરંતુ જટિલ ટેકનોલોજી ખરેખર ક્યાં ફરક પાડે છે? તે એવી એપ્લિકેશન્સમાં શ્રેષ્ઠ છે જેને મોટા ડેટાસેટ્સ પર ભારે, પેરેલલાઇઝેબલ ગણતરીની જરૂર હોય છે.
- વેબએસેમ્બલી (Wasm): આ કિલર યુઝ કેસ છે. C++, Rust, અને Go જેવી ભાષાઓમાં મલ્ટિથ્રેડિંગ માટે પરિપક્વ સમર્થન છે. Wasm વિકાસકર્તાઓને આ હાલની ઉચ્ચ-પ્રદર્શન, મલ્ટિ-થ્રેડેડ એપ્લિકેશન્સ (જેમ કે ગેમ એન્જિન, CAD સોફ્ટવેર અને વૈજ્ઞાનિક મોડલ્સ) ને બ્રાઉઝરમાં ચલાવવા માટે કમ્પાઇલ કરવાની મંજૂરી આપે છે, થ્રેડ કમ્યુનિકેશન માટે અંતર્ગત મિકેનિઝમ તરીકે
SharedArrayBuffer
નો ઉપયોગ કરીને. - ઇન-બ્રાઉઝર ડેટા પ્રોસેસિંગ: મોટા પાયે ડેટા વિઝ્યુલાઇઝેશન, ક્લાયન્ટ-સાઇડ મશીન લર્નિંગ મોડેલ ઇન્ફરન્સ, અને વૈજ્ઞાનિક સિમ્યુલેશન્સ જે મોટા પ્રમાણમાં ડેટા પર પ્રક્રિયા કરે છે તેને નોંધપાત્ર રીતે વેગ આપી શકાય છે.
- મીડિયા એડિટિંગ: ઉચ્ચ-રીઝોલ્યુશન છબીઓ પર ફિલ્ટર્સ લાગુ કરવા અથવા સાઉન્ડ ફાઇલ પર ઑડિઓ પ્રોસેસિંગ કરવાને ટુકડાઓમાં વિભાજીત કરી શકાય છે અને બહુવિધ વર્કર્સ દ્વારા સમાંતર રીતે પ્રક્રિયા કરી શકાય છે, જે વપરાશકર્તાને વાસ્તવિક-સમયમાં પ્રતિસાદ પૂરો પાડે છે.
- ઉચ્ચ-પ્રદર્શન ગેમિંગ: આધુનિક ગેમ એન્જિનો ભૌતિકશાસ્ત્ર, AI અને એસેટ લોડિંગ માટે મલ્ટિથ્રેડિંગ પર ભારે આધાર રાખે છે.
SharedArrayBuffer
કન્સોલ-ગુણવત્તાવાળી રમતો બનાવવાનું શક્ય બનાવે છે જે સંપૂર્ણપણે બ્રાઉઝરમાં ચાલે છે.
પડકારો અને અંતિમ વિચારણાઓ
જ્યારે SharedArrayBuffer
પરિવર્તનશીલ છે, તે કોઈ રામબાણ ઈલાજ નથી. તે એક નિમ્ન-સ્તરનું સાધન છે જેને સાવચેતીપૂર્વક સંભાળવાની જરૂર છે.
- જટિલતા: કોન્કરન્ટ પ્રોગ્રામિંગ કુખ્યાત રીતે મુશ્કેલ છે. રેસ કન્ડિશન્સ અને ડેડલોક્સને ડીબગ કરવું અતિ પડકારજનક હોઈ શકે છે. તમારે તમારી એપ્લિકેશન સ્થિતિ કેવી રીતે સંચાલિત થાય છે તે વિશે અલગ રીતે વિચારવું આવશ્યક છે.
- ડેડલોક્સ: ડેડલોક ત્યારે થાય છે જ્યારે બે કે તેથી વધુ થ્રેડો હંમેશ માટે અવરોધિત થઈ જાય છે, દરેક બીજા દ્વારા સંસાધન મુક્ત થવાની રાહ જોતા હોય છે. જો તમે જટિલ લોકીંગ મિકેનિઝમ્સને ખોટી રીતે અમલમાં મૂકો તો આ થઈ શકે છે.
- સુરક્ષા ઓવરહેડ: ક્રોસ-ઓરિજિન આઇસોલેશનની જરૂરિયાત એક નોંધપાત્ર અવરોધ છે. જો તેઓ જરૂરી CORS/CORP હેડરોને સમર્થન ન આપતા હોય તો તે તૃતીય-પક્ષ સેવાઓ, જાહેરાતો અને ચુકવણી ગેટવે સાથેના એકીકરણને તોડી શકે છે.
- દરેક સમસ્યા માટે નથી: સરળ બેકગ્રાઉન્ડ કાર્યો અથવા I/O ઓપરેશન્સ માટે,
postMessage()
સાથે પરંપરાગત વેબ વર્કર મોડેલ ઘણીવાર સરળ અને પર્યાપ્ત હોય છે.SharedArrayBuffer
માટે ત્યારે જ પહોંચો જ્યારે તમારી પાસે મોટા પ્રમાણમાં ડેટા સંડોવતો સ્પષ્ટ, CPU-બાઉન્ડ બોટલનેક હોય.
નિષ્કર્ષ
SharedArrayBuffer
, Atomics
અને વેબ વર્કર્સ સાથે મળીને, વેબ ડેવલપમેન્ટ માટે એક પેરાડાઈમ શિફ્ટનું પ્રતિનિધિત્વ કરે છે. તે સિંગલ-થ્રેડેડ મોડેલની સરહદોને તોડી નાખે છે, બ્રાઉઝરમાં શક્તિશાળી, પ્રદર્શનશીલ અને જટિલ એપ્લિકેશન્સના નવા વર્ગને આમંત્રિત કરે છે. તે વેબ પ્લેટફોર્મને ગણતરીની રીતે સઘન કાર્યો માટે નેટિવ એપ્લિકેશન ડેવલપમેન્ટ સાથે સમાન સ્તર પર મૂકે છે.
કોન્કરન્ટ જાવાસ્ક્રિપ્ટમાંની યાત્રા પડકારજનક છે, જે સ્ટેટ મેનેજમેન્ટ, સિંક્રોનાઇઝેશન અને સુરક્ષા માટે સખત અભિગમની માંગ કરે છે. પરંતુ વેબ પર જે શક્ય છે તેની મર્યાદાઓને આગળ વધારવા માંગતા વિકાસકર્તાઓ માટે—રીઅલ-ટાઇમ ઑડિઓ સિન્થેસિસથી લઈને જટિલ 3D રેન્ડરિંગ અને વૈજ્ઞાનિક કમ્પ્યુટિંગ સુધી—SharedArrayBuffer
માં નિપુણતા મેળવવી હવે માત્ર એક વિકલ્પ નથી; તે વેબ એપ્લિકેશન્સની આગામી પેઢીના નિર્માણ માટે એક આવશ્યક કૌશલ્ય છે.