سلاسل WebAssembly جاهزة للتجربة في Chrome 70

تم توفير دعم سلاسل محادثات WebAssembly في الإصدار 70 من Chrome في إطار إصدار تجريبي للمنشأ.

Alex Danilo

يتيح WebAssembly (Wasm) تجميع الرموز البرمجية المكتوبة بلغة C++ وغيرها من اللغات لتشغيلها على الويب. من الميزات المفيدة جدًا للتطبيقات الأصلية هي إمكانية استخدام مؤشرات الترابط، وهي عنصر أساسي للحساب المتوازي. سيعرف معظم مطوّري لغة C وC++ عن pthreads، وهي واجهة برمجة تطبيقات متوافقة لإدارة المواضيع في التطبيق.

عملت مجموعة WebAssembly المجتمعية على توفير سلاسل المحادثات على الويب لتفعيل التطبيقات المتعدّدة سلاسل المحادثات الحقيقية. كجزء من هذا الجهد، نفَّذ V8 التوافق اللازم مع المهام في محرّك WebAssembly، وهو متاح من خلال الإصدار التجريبي من الإصدار الأول. تتيح مراحل التجربة والتقييم للمطوّرين تجربة ميزات الويب الجديدة قبل أن يتم توحيدها بالكامل. يتيح لنا ذلك جمع ملاحظات من المطوّرين الذين يجرّبون الميزات الجديدة، ما يُعدّ أمرًا مهمًا للتحقّق من صحة الميزات الجديدة وتحسينها.

يتيح الإصدار 70 من Chrome استخدام سلاسل المهام لـ WebAssembly، ونشجّع المطوّرين المهتمين على بدء استخدامها وإرسال ملاحظاتهم إلينا.

سلاسل المحادثات؟ ماذا عن Workers؟

تتيح المتصفّحات استخدام ميزة "المعالجة المتزامنة" من خلال Web Worker منذ عام 2012 في الإصدار 4 من Chrome. وبعبارة أخرى، من الطبيعي سماع عبارات مثل "في الخيط الرئيسي" وما إلى ذلك. ومع ذلك، لا تشارك Web Worker البيانات القابلة للتغيير مع بعضها، بل تعتمد بدلاً من ذلك على مشاركة الرسائل للتواصل. في الواقع، يخصّص Chrome محرك V8 جديدًا لكلّ منها (يُعرف باسم "الوحدات المنعزلة"). لا تشارك العزلات أي رمز مُجمَّع أو عناصر JavaScript، وبالتالي لا يمكنها مشاركة البيانات القابلة للتغيير مثل pthreads.

من ناحية أخرى، سلاسل WebAssembly هي سلاسل يمكنها مشاركة ذاكرة Wasm نفسها. يتمّ توفير مساحة التخزين الأساسية للذاكرة المشتركة باستخدام SharedArrayBuffer، وهو عنصر أساسي في JavaScript يسمح بمشاركة محتوى ArrayBuffer واحد في الوقت نفسه بين خيوط العمل. يتم تشغيل كل سلسلة محادثات WebAssembly في Web Worker، ولكن تسمح لهم ذاكرة Wasm المشتركة بالعمل بشكل مشابه لما يحدث على منصات الأصلية. وهذا يعني أنّ التطبيقات التي تستخدم مؤشرات تسلسل Wasm هي المسؤولة عن إدارة الوصول إلى الذاكرة المشتركة كما هو الحال في أي تطبيق تقليدي يتضمّن مؤشرات تسلسل. هناك العديد من مكتبات الرموز البرمجية الحالية المكتوبة بلغة C أو C++ التي تستخدِم pthreads، ويمكن تجميعها إلى Wasm وتشغيلها في وضع خيوط حقيقية، ما يسمح للمزيد من النوى بالعمل على البيانات نفسها في الوقت نفسه.

مثال بسيط

في ما يلي مثال على برنامج C بسيط يستخدم مؤشرات الترابط.

#include <pthread.h>
#include <stdio.h>

// Calculate Fibonacci numbers shared function
int fibonacci(int iterations) {
    int     val = 1;
    int     last = 0;

    if (iterations == 0) {
        return 0;
    }
    for (int i = 1; i < iterations; i++) {
        int     seq;

        seq = val + last;
        last = val;
        val = seq;
    }
    return val;
}
// Start function for the background thread
void *bg_func(void *arg) {
    int     *iter = (void *)arg;

    *iter = fibonacci(*iter);
    return arg;
}
// Foreground thread and main entry point
int main(int argc, char *argv[]) {
    int         fg_val = 54;
    int         bg_val = 42;
    pthread_t   bg_thread;

    // Create the background thread
    if (pthread_create(&bg_thread, NULL, bg_func, &bg_val)) {
        perror("Thread create failed");
        return 1;
    }
    // Calculate on the foreground thread
    fg_val = fibonacci(fg_val);
    // Wait for background thread to finish
    if (pthread_join(bg_thread, NULL)) {
        perror("Thread join failed");
        return 2;
    }
    // Show the result from background and foreground threads
    printf("Fib(42) is %d, Fib(6 * 9) is %d\n", bg_val, fg_val);

    return 0;
}

تبدأ هذه التعليمة البرمجية بالدالة main() التي تحدّد متغيرين fg_val و bg_val. هناك أيضًا دالة تُسمى fibonacci()، والتي سيتم استدعاؤها من خلال كل من المهام في هذا المثال. تنشئ دالة main() سلسلة مهام في الخلفية باستخدام pthread_create() لحساب قيمة تسلسل أرقام فيبوناتشي التي تتوافق مع قيمة المتغيّر bg_val. في الوقت نفسه، تعمل دالة main() التي تعمل في سلسلة المهام التي تعمل في المقدّمة على احتسابها للمتغيّر fg_val. بعد اكتمال تشغيل سلسلت الرسائل الخلفية، يتم طباعة النتائج.

تجميع التطبيق لتضمين ميزة سلاسل المحادثات

أولاً، يجب تثبيت حزمة emscripten SDK ، ويُفضّل استخدام الإصدار 1.38.11 أو إصدار أحدث. لإنشاء مثال التعليمات البرمجية مع تفعيل مؤشرات الترابط لتشغيلها في المتصفّح، علينا تمرير علامتَين إضافيتَين إلى مترجم emscripten emcc. تبدو سطر الأوامر على النحو التالي:

emcc -O2 -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=2 -o test.js test.c

تعمل وسيطة سطر الأوامر "-s USE_PTHREADS=1" على تفعيل ميزة توفُّر مؤشرات الترابط ل وحدة WebAssembly المجمّعة، وتطلب وسيطة "-s PTHREAD_POOL_SIZE=2" من المُجمِّع إنشاء مجموعة من مؤشّرتي ترابط.

عند تشغيل البرنامج، سيتم تحميل وحدة WebAssembly، وإنشاء Web Worker لكل سلسلة مهام في مجموعة سلاسل المهام، ومشاركة الوحدة مع كل عامل، وفي هذه الحالة يكون عددهم اثنين، وسيتم استخدامهما عند إجراء طلب إلى pthread_create(). ينشئ كل عامل مثيلًا لوحدة Wasm باستخدام الذاكرة نفسها، ما يتيح له التعاون مع الآخرين. تشترك أحدث تغييرات V8 في الإصدار 7.0 مع الرمز الأصلي المجمّع لوحدات Wasm التي يتم تمريرها بين العوامل، ما يسمح حتى للتطبيقات الكبيرة جدًا بالتوسع إلى العديد من العوامل. يُرجى العلم أنّه من المنطقي التأكّد من أنّ حجم مجموعة مؤشرات الترابط يساوي الحد الأقصى لعدد مؤشرات الترابط التي يحتاجها تطبيقك، وإلا قد يتعذّر إنشاء مؤشر الترابط. في الوقت نفسه، إذا كان حجم مجموعة مؤشرات الترابط كبيرًا جدًا، سيتم إنشاء Web Workers غير ضرورية لن تؤدي أي مهمة سوى استخدام الذاكرة.

كيفية تجربة الميزة

إنّ أسرع طريقة لاختبار وحدة WebAssembly هي تفعيل ميزة الإصدار التجريبي من خيوط WebAssembly في Chrome 70 والإصدارات الأحدث. انتقِل إلى عنوان URL about://flags في المتصفّح كما هو موضّح أدناه:

صفحة ميزات Chrome التجريبية

بعد ذلك، ابحث عن إعداد سلاسل مهام WebAssembly التجريبية التي تبدو على النحو التالي:

إعداد سلاسل محادثات WebAssembly

غيِّر الإعداد إلى مفعَّل كما هو موضَّح أدناه، ثم أعِد تشغيل المتصفّح.

تم تفعيل إعداد سلاسل WebAssembly

بعد إعادة تشغيل المتصفّح، يمكننا محاولة تحميل ملف WebAssembly المكوّن من سلاسل محادثات باستخدام صفحة HTML بسيطة تحتوي على هذا المحتوى فقط:

<!DOCTYPE html>
<html>
  <title>Threads test</title>
  <body>
    <script src="test.js"></script>
  </body>
</html>

لتجربة هذه الصفحة، عليك تشغيل أحد أشكال خادم الويب وتحميله من المتصفّح. سيؤدي ذلك إلى تحميل وحدة WebAssembly وتشغيلها. يؤدي فتح DevTools إلى عرض الناتج من عملية التشغيل، ومن المفترض أن يظهر لك ناتج مشابه لملف ملف المخرجات أدناه في وحدة التحكّم:

نتائج وحدة التحكّم من برنامج fibonacci

تم تنفيذ برنامج WebAssembly مع سلاسل المهام بنجاح. ننصحك بتجربة تطبيقك المكوّن من سلاسل محادثات باستخدام الخطوات الموضّحة أعلاه.

الاختبار في الميدان باستخدام مرحلة التجربة والتقييم

إنّ تجربة سلاسل المحادثات من خلال تفعيل علامات الإصدار التجريبي في المتصفّح أمر جيد لأغراض التطوير، ولكن إذا أردت اختبار تطبيقك في الميدان، يمكنك إجراء ذلك من خلال ما يُعرف باسم الإصدار التجريبي من المصدر.

تتيح لك تجارب الإصدارات العلنية الأولى تجربة الميزات التجريبية مع المستخدمين من خلال الحصول على رمز اختبار مرتبط بنطاقك. يمكنك بعد ذلك نشر تطبيقك والتوقع أن يعمل في متصفّح يمكنه إتاحة الميزة التي تختبرها (في هذا الحالة، الإصدار 70 من Chrome فصاعدًا). للحصول على رمزك المميّز لإجراء تجربة تجريبية، استخدِم نموذج الطلب المتاح هنا.

استضفنا المثال البسيط أعلاه باستخدام رمز مميز للإصدار التجريبي من المصدر، حتى تتمكّن من تجربته بنفسك بدون الحاجة إلى إنشاء أيّ محتوى.

إذا كنت تريد معرفة ما يمكن أن تُحقّقه 4 سلاسل محادثات تعمل بشكل موازٍ للفن ASCII، عليك أولاً التمعن في هذا العرض التجريبي.

أرسل لنا تعليقاتك

خيوط WebAssembly هي عناصر أساسية جديدة ومفيدة للغاية لنقل التطبيقات إلى الويب. أصبح من الممكن الآن تشغيل تطبيقات C وC++ والمكتبات التي تتطلّب pthreads في بيئة WebAssembly.

نتطلّع إلى الحصول على ملاحظات من المطوّرين الذين يجرّبون هذه الميزة، لأنّها ستساعد في إعلامنا بمدى فائدة هذه الميزة وتحديد معاييرها. إنّ أفضل طريقة لإرسال الملاحظات هي الإبلاغ عن المشاكل و/أو إشراكك في عملية التوحيد في مجموعة WebAssembly المجتمعية.