WebAssembly Threads آماده امتحان در کروم 70 است

پشتیبانی از رشته WebAssembly در Chrome 70 تحت یک آزمایش اولیه ارسال شده است.

Alex Danilo

WebAssembly (Wasm) کامپایل کدهای نوشته شده در C++ و سایر زبان ها را برای اجرا در وب فعال می کند. یکی از ویژگی‌های بسیار مفید برنامه‌های بومی، توانایی استفاده از رشته‌ها است - یک ویژگی اولیه برای محاسبات موازی. اکثر توسعه دهندگان C و C++ با pthreads آشنا هستند که یک API استاندارد شده برای مدیریت رشته در یک برنامه کاربردی است.

گروه انجمن WebAssembly روی آوردن رشته ها به وب کار می کند تا برنامه های چند رشته ای واقعی را فعال کند. به عنوان بخشی از این تلاش، V8 پشتیبانی لازم را برای موضوعات در موتور WebAssembly، که از طریق Origin Trial در دسترس است، اجرا کرده است. Origin Trials به توسعه دهندگان این امکان را می دهد که ویژگی های وب جدید را قبل از اینکه کاملاً استاندارد شوند آزمایش کنند. این به ما امکان می دهد تا بازخورد دنیای واقعی را از توسعه دهندگان بی باک جمع آوری کنیم، که برای اعتبارسنجی و بهبود ویژگی های جدید بسیار مهم است.

نسخه Chrome 70 از رشته‌هایی برای WebAssembly پشتیبانی می‌کند و ما توسعه‌دهندگان علاقه‌مند را تشویق می‌کنیم که از آنها استفاده کنند و به ما بازخورد بدهند.

رشته ها؟ کارگران چطور؟

مرورگرها از سال 2012 در Chrome 4 از موازی سازی از طریق Web Workers پشتیبانی می کنند. در واقع شنیدن عباراتی مانند "در موضوع اصلی" و غیره طبیعی است. با این حال، Web Workers داده های قابل تغییر را بین خود به اشتراک نمی گذارند، در عوض برای برقراری ارتباط به انتقال پیام متکی هستند. در واقع کروم یک موتور V8 جدید برای هر یک از آنها (به نام ایزوله) اختصاص می دهد. ایزوله ها نه کد کامپایل شده و نه اشیاء جاوا اسکریپت را به اشتراک می گذارند و بنابراین نمی توانند داده های قابل تغییر مانند pthread ها را به اشتراک بگذارند.

از طرف دیگر، رشته‌های WebAssembly رشته‌هایی هستند که می‌توانند حافظه Wasm یکسانی را به اشتراک بگذارند. ذخیره سازی اساسی حافظه مشترک با یک SharedArrayBuffer انجام می شود، یک جاوا اسکریپت ابتدایی که امکان اشتراک گذاری محتویات یک ArrayBuffer را به طور همزمان بین کارگران فراهم می کند. هر رشته WebAssembly در یک Web Worker اجرا می شود، اما حافظه مشترک Wasm آنها به آنها اجازه می دهد تا مانند سیستم عامل های بومی کار کنند. این بدان معناست که برنامه‌هایی که از رشته‌های Wasm استفاده می‌کنند، مسئول مدیریت دسترسی به حافظه مشترک مانند هر برنامه سنتی رشته‌ای هستند. بسیاری از کتابخانه‌های کد موجود به زبان C یا C++ نوشته شده‌اند که از pthread‌ها استفاده می‌کنند و می‌توان آن‌ها را در 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() شروع می شود که 2 متغیر fg_val و bg_val را اعلام می کند. همچنین تابعی به نام fibonacci() وجود دارد که توسط هر دو رشته در این مثال فراخوانی می شود. تابع main() با استفاده از pthread_create() یک رشته پس زمینه ایجاد می کند که وظیفه آن محاسبه مقدار دنباله عدد فیبوناچی مربوط به مقدار متغیر bg_val است. در همین حال، تابع main() که در رشته پیش زمینه اجرا می شود، آن را برای متغیر fg_val محاسبه می کند. پس از اتمام کار رشته پس زمینه، نتایج چاپ می شوند.

کامپایل برای پشتیبانی از موضوع

ابتدا باید emscripten SDK را نصب کنید، ترجیحاً نسخه 1.38.11 یا بالاتر. برای ساختن کد مثال خود با رشته‌هایی که برای اجرا در مرورگر فعال هستند ، باید چند پرچم اضافی را به کامپایلر emscripten emc ارسال کنیم. خط فرمان ما به شکل زیر است:

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 ' به کامپایلر می گوید که مجموعه ای از دو (2) رشته تولید کند.

هنگامی که برنامه اجرا می شود، ماژول WebAssembly را در زیر هود بارگذاری می کند، یک Web Worker برای هر یک از رشته های موجود در Thread Pool ایجاد می کند، ماژول را با هر یک از کارگران به اشتراک می گذارد، در این مورد 2 است، و از آن ها استفاده می شود. هر زمان که به pthread_create() فراخوانی شود. هر کارگر ماژول Wasm را با همان حافظه نمونه سازی می کند و به آنها امکان همکاری می دهد. جدیدترین تغییرات V8 در 7.0 کد بومی کامپایل شده ماژول‌های Wasm را به اشتراک می‌گذارد که بین کارگران ارسال می‌شود، که حتی به برنامه‌های بسیار بزرگ اجازه می‌دهد تا برای بسیاری از کارگران مقیاس شوند. توجه داشته باشید، منطقی است که مطمئن شوید اندازه مجموعه موضوعات برابر با حداکثر تعداد رشته‌هایی است که برنامه شما نیاز دارد، در غیر این صورت ممکن است ایجاد رشته با شکست مواجه شود. در همان زمان، اگر اندازه thread pool خیلی بزرگ باشد، Web Workers غیرضروری ایجاد می‌کنید که به جز استفاده از حافظه کاری انجام نمی‌دهند.

چگونه آن را امتحان کنیم

سریع‌ترین راه برای آزمایش ماژول WebAssembly ما، فعال کردن پشتیبانی از رشته‌های آزمایشی WebAssembly در Chrome 70 به بعد است. همانطور که در زیر نشان داده شده است به URL about://flags در مرورگر خود بروید:

صفحه پرچم‌های کروم

سپس، تنظیمات آزمایشی رشته‌های WebAssembly را پیدا کنید که به شکل زیر است:

تنظیمات رشته های WebAssembly

مطابق شکل زیر تنظیمات را به Enabled تغییر دهید، سپس مرورگر خود را مجددا راه اندازی کنید.

تنظیمات رشته های WebAssembly فعال شد

پس از راه‌اندازی مجدد مرورگر، می‌توانیم ماژول WebAssembly رشته‌ای را با یک صفحه حداقل HTML بارگیری کنیم که فقط حاوی این محتوا است:

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

برای امتحان این صفحه، باید نوعی از وب سرور را اجرا کنید و آن را از مرورگر خود بارگیری کنید. این باعث می شود که ماژول WebAssembly بارگیری و اجرا شود. باز کردن DevTools خروجی اجرا شده را به ما نشان می دهد و شما باید چیزی شبیه تصویر خروجی زیر را در کنسول ببینید:

خروجی کنسول از برنامه فیبوناچی

برنامه WebAssembly ما با موضوعات با موفقیت اجرا شد! ما شما را تشویق می کنیم که با استفاده از مراحل ذکر شده در بالا، برنامه رشته ای خود را امتحان کنید.

تست در این زمینه با آزمایش مبدا

آزمایش رشته‌ها با روشن کردن پرچم‌های آزمایشی در مرورگر برای اهداف توسعه خوب است، اما اگر می‌خواهید برنامه خود را در این زمینه آزمایش کنید، می‌توانید این کار را با چیزی که به عنوان آزمایش اولیه شناخته می‌شود انجام دهید.

آزمایش‌های مبدأ به شما امکان می‌دهد ویژگی‌های آزمایشی را با دریافت یک نشانه آزمایشی که به دامنه شما مرتبط است، با کاربران خود امتحان کنید. سپس می‌توانید برنامه خود را اجرا کنید و انتظار داشته باشید که در مرورگری کار کند که می‌تواند از ویژگی مورد آزمایش شما (در این مورد Chrome 70 به بعد) پشتیبانی کند. برای به دست آوردن رمز خود برای اجرای آزمایشی اصلی، از فرم درخواست اینجا استفاده کنید.

ما مثال ساده خود را در بالا با استفاده از یک نشانه آزمایشی اصلی میزبانی کرده‌ایم، بنابراین می‌توانید بدون نیاز به ساخت چیزی آن را برای خودتان امتحان کنید .

اگر می خواهید ببینید 4 رشته در حال اجرا به صورت موازی چه کاری می توانند برای هنر ASCII انجام دهند، پس باید به این دمو نیز نگاهی بیندازید!

به ما بازخورد بدهید

رشته های WebAssembly یک روش اولیه بسیار مفید برای انتقال برنامه های کاربردی به وب هستند. اکنون می‌توان برنامه‌ها و کتابخانه‌های C و C++ را که نیاز به پشتیبانی از pthreads در محیط WebAssembly دارند، اجرا کرد.

ما به دنبال بازخورد توسعه‌دهندگانی هستیم که این ویژگی را امتحان می‌کنند، زیرا به اطلاع‌رسانی فرآیند استانداردسازی و همچنین اعتبارسنجی مفید بودن آن کمک می‌کند. بهترین راه برای ارسال بازخورد، گزارش مشکلات و/یا درگیر شدن با فرآیند استانداردسازی در گروه انجمن WebAssembly است.