דף הבית » קידוד » מבוא לזיכרון משותף ב - JavaScript

    מבוא לזיכרון משותף ב - JavaScript

    זכרון משותף היא תכונה מתקדמת של JavaScript, כי הנושאים (במקביל להורג חלקים של תהליך) יכול למנף. שיתוף הזיכרון פירושו לא נתקל בבעיה של העברת נתונים מעודכנים בין האשכולות וכל האשכולות יכולים לגשת ולעדכן את אותם נתונים בזיכרון המשותף.

    זה לא נשמע נחמד? טוב, כמעט. פוסט זה נראה כיצד להשתמש בזיכרון משותף ב - JavaScript - - וכיצד להחליט אם זה מה שאתה באמת רוצה לעשות.

    יתרונות וחסרונות של זיכרון משותף

    אנו משתמשים עובדי אינטרנט ל ליצור חוטים ב- JavaScript. Web Workers API מאפשר לנו ליצור שרשורי עובדים שניתן להשתמש בהם לבצע קוד ברקע כך החוט המרכזי הוא חופשי להמשיך בביצוע שלה, אולי עיבוד UI אירועים, הבטחת שום הקפאה UI.

    חוטי עובדים לרוץ במקביל עם חוט הראשי אחד את השני. ביצוע סימולטני של חלקים שונים של משימה הוא חיסכון בזמן. אתה מסיים מהר יותר, אבל יש לו גם קבוצה משלו של בעיות.

    וודא שכל חוט מקבל את המשאבים הדרושים ומתקשר אחד עם השני בזמן היא משימה בפני עצמה, שבה תקלה יכולה לגרום לתוצאה מפתיעה. או אם חוט אחד הוא שינוי נתונים ועוד אחד קורא את זה באותו הזמן, מה לדעתך החוט השני יראה? הנתונים המעודכנים או הישנים?

    עם זאת, עובדי האינטרנט הם לא כל כך קל לפשל. במהלך התקשורת שלהם באמצעות הודעות, הנתונים הם שולחים אחד את השני לא מקורי אלא עותק, כלומר הם לא נתח אותם נתונים. הם להעביר עותקים של נתונים זה לזה במקרה הצורך.

    אבל שיתוף הוא אכפתיות, וכן מספר נושאים עשוי גם צריך להסתכל על אותם נתונים בו זמנית ולשנות אותם. לכן, איסור שיתוף הוא גדול לא. זה המקום שבו שיתופי פעולה האובייקט נכנס לתמונה. זה ייתן לנו שיתוף נתונים בינאריים בין אשכולות מרובים.

    ה שיתופי פעולה אובייקט

    במקום להעביר את הנתונים עותקים בין הנושאים, אנחנו להעביר עותקים של שיתופי פעולה אובייקט. א שיתופי פעולה אובייקט מצביע על הזיכרון שבו נשמרים הנתונים.

    אז, גם כאשר עותקים של שיתופי פעולה מועברים בין חוטים, הם כולם ימשיכו להצביע על אותו זיכרון שבו נשמרים הנתונים המקוריים. החוטים, כך, יכול להציג ולעדכן את הנתונים באותו זיכרון.

    עובדי רשת ללא זכרון משותף

    כדי לראות כיצד עובד אינטרנט עובד ללא שימוש בזיכרון משותף, אנחנו ליצור חוט עובד ו להעביר כמה נתונים אליו.

    ה index.html הקובץ מחזיק את התסריט הראשי בתוך א , כפי שניתן לראות למטה:

     const w = עובד חדש ('worker.js'); var n = 9; w.postMessage (n); 

    ה worker.js הקובץ נושא את סקריפט עובדYou

     onmessage = (e) => console.group ('[worker]'); console.log ('נתונים שהתקבלו מחוט המרכזי:% i', e.data); console.groupEnd ();  

    באמצעות הקוד לעיל, אנו מקבלים את הדברים הבאים פלט במסוףYou

     [עובד] נתונים שהתקבלו מחוט המרכזי: 9 

    אתה יכול לקרוא את ההודעה הנ"ל על עובדי אינטרנט עבור הסבר קוד מלא של קטעי הקוד.

    לעת עתה, יש לזכור כי הנתונים נשלח הלוך וחזור בין החוטים משתמש ב הודעה () שיטה. הנתונים הם קיבל בצד השני על ידי הודעה מנהל אירועים, כמו הערך של האירוע נתונים נכס.

    עכשיו, אם אנחנו לשנות את הנתונים האם הוא יופיע מעודכן בסוף המקבל? בוא נראה:

     const w = עובד חדש ('worker.js'); var n = 9; w.postMessage (n); n = 1; 

    כצפוי, יש נתונים לא עודכןYou

     [עובד] נתונים שהתקבלו מחוט המרכזי: 9 

    למה זה יהיה, בכל זאת? זה רק שיבוט שנשלח לעובד מהתסריט הראשי.

    עובדי רשת עם זכרון משותף

    עכשיו, אנחנו נעשה להשתמש ב שיתופי פעולה אובייקט בדוגמה זהה. אנחנו יכולים ליצור חדש שיתופי פעולה למשל על ידי משתמש ב חדש מילת מפתח. הבנאי לוקח פרמטר אחד; א ערך אורך בתים, ציון הגודל של המאגר.

     const w = עובד חדש ('worker.js'); buff = SharedArrayBuffer חדש (1); var arr = חדש Int8Array (buff); / * הגדרת נתונים * / arr [0] = 9; / * שליחת המאגר (להעתיק) לעובד * / w.postMessage (buff); 

    שים לב כי שיתופי פעולה אובייקט מייצג רק אזור זיכרון משותף. ל לראות ולשנות את הנתונים הבינאריים, אנו צריכים להשתמש במבנה נתונים מתאים (a TypedArray או תצוגת נתונים אובייקט).

    בתוך ה index.html הקובץ לעיל, חדש שיתופי פעולה נוצר, עם רק אורך אחד בתים. ואז, חדש Int8Array, שהוא סוג אחד של TypedArray אובייקטים, משמש להגדיר את הנתונים “9” בחלל הבתים המסופק.

     onmessage = (e) => var arr = Int8Array חדש (e.data); console.group ('[עובד]'); console.log ('נתונים שהתקבלו מחוט המרכזי:% i', arr [0]); console.groupEnd ();  

    Int8Array משמש גם את העובד, ל להציג את הנתונים במאגר.

    ה הערך הצפוי מופיע במסוף מחוט העובד, וזה בדיוק מה שרצינו:

     [עובד] נתונים שהתקבלו מחוט המרכזי: 9 

    עכשיו, בואו עדכן את הנתונים בחוט הראשי כדי לראות אם השינוי בא לידי ביטוי בעובד.

     const w = New Worker ('worker.js'), buff = SharedArrayBuffer חדש (1); var arr = חדש Int8Array (buff); / * הגדרת נתונים * / arr [0] = 9; / * שליחת המאגר (להעתיק) לעובד * / w.postMessage (buff); / * שינוי הנתונים * / arr [0] = 1;

    וכפי שניתן לראות בהמשך, העדכון האם משקף בתוך העובד!

     [עובד] נתונים שהתקבלו מחוט המרכזי: 1 

    אבל, את הקוד גם צריך לעבוד בכיוון ההפוך: כאשר הערך בעובד משתנה בהתחלה, זה גם צריך להיות מעודכן כאשר הוא מודפס מהחוט הראשי.

    במקרה זה, הקוד שלנו נראה כך:

     onmessage = (e) => var arr = Int8Array חדש (e.data); console.group ('[עובד]'); console.log ('נתונים שהתקבלו מחוט המרכזי:% i', arr [0]); console.groupEnd (); / * שינוי הנתונים * / arr [0] = 7; / * פרסום על חוט הראשי * / postMessage ("); 

    ה הנתונים משתנים אצל העובד ו הודעה ריקה מוצבת בחוט הראשי מסמן כי הנתונים במאגר השתנה והוא מוכן חוט הראשי להיות outputted.

     const w = New Worker ('worker.js'), buff = SharedArrayBuffer חדש (1); var arr = חדש Int8Array (buff); / * הגדרת נתונים * / arr [0] = 9; / * שליחת המאגר (להעתיק) לעובד * / w.postMessage (buff); / * שינוי הנתונים * / arr [0] = 1; / * הדפסת הנתונים לאחר שהעובד שינה אותה * / w.onmessage = (e) => console.group ('[main]'); console.log ('נתונים מעודכנים שהתקבלו מחוט עובדים:% i', arr [0]); console.groupEnd ();  

    וגם, זה עובד, יותר מדי! הנתונים במאגר זהים לנתונים בתוך העובד.

     [עובד] נתונים שהתקבלו מחוט המרכזי: 1 [main] נתונים מעודכנים שהתקבלו מחוט עובדים: 7 

    הערך מתעדכן בשני המקרים; שני הנושאים העיקריים והעובדים מציגים ומשנים את אותם נתונים.

    מילים סופיות

    כפי שהזכרתי קודם, באמצעות זיכרון משותף ב- JavaScript הוא לא בלי חסרונות. זה תלוי במפתחים כדי להבטיח את רצף של ביצוע קורה כצפוי ואין שני פתילים רצים כדי לקבל את אותם נתונים כי אף אחד לא יודע מי ייקח את הגביע.

    אם אתה מעוניין יותר זיכרון משותף, יש להסתכל על התיעוד של אטומים אובייקט. ה Atomics אובייקט יכול לעזור לך עם כמה קשיים, על ידי צמצום אופיו הבלתי צפוי של קריאה / כתיבה מהזיכרון המשותף.