لینک کوتاه مطلب : https://hsgar.com/?p=5577

زمان اجرا چیست؟ در اینجا نحوه کار توکیو در زیر کاپوت آورده شده است

این پست شامل گزیده هایی از کتاب من کلاه سیاه زنگ می باشد

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

Rust زمینه اجرای مورد نیاز برای اجرای Futures و Streams را فراهم نمی کند. این زمینه اجرا a نامیده می شود زمان اجرا. شما نمی توانید اجرا کنید async برنامه Rust بدون زمان اجرا.

3 محبوب ترین زمان اجرا عبارتند از:

زمان اجرا دانلودهای همیشگی (ژانویه 2022) شرح
توکیو 42,874,882 یک پلتفرم I/O مبتنی بر رویداد و غیرمسدود برای نوشتن برنامه‌های غیرهمزمان با پشتیبانی I/O.
async-std 5,875,271 نسخه Async کتابخانه استاندارد Rust
smol 1,187,600 یک زمان اجرا ناهمگام کوچک و سریع

با این حال، یک مشکل وجود دارد: امروزه، زمان‌های اجرا قابل تعامل نیستند و نیاز به تأیید ویژگی‌های آن‌ها در کد دارند: شما نمی‌توانید به راحتی یک زمان اجرا را با تغییر تنها 1-2 خط کد، به راحتی با زمان اجرا دیگری تعویض کنید.

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

معرفی توکیو

توکیو زمان اجرا Rust async است که بیشترین پشتیبانی را از طرف جامعه دارد و حامیان زیادی دارد (مانند Discord، Fly.io، و Embark) که به آن اجازه می دهند مشارکت کنندگان پولی!

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

حلقه(های) رویداد

در هسته همه async زمان اجرا (خواه در Rust، Node.js یا زبان های دیگر) هستند حلقه های رویداد، همچنین به نام پردازنده ها.

در واقعیت، برای عملکرد بهتر، اغلب چندین پردازنده در هر برنامه وجود دارد، یکی در هر هسته CPU.

هر حلقه رویداد دارای صف وظایف خاص خود استawaitبرای تکمیل Tokio’s به عنوان یک زمان اجرای کار دزدی شناخته شده است. هر پردازنده می تواند وظیفه را در صف پردازشگر دیگری بدزدد اگر پردازنده خودش خالی باشد (یعنی کاری برای انجام دادن نداشته باشد و بیکار “نشسته” باشد).

برای کسب اطلاعات بیشتر در مورد انواع مختلف حلقه های رویداد، می توانید این مقاله عالی توسط کارل لرچه را بخوانید: https://tokio.rs/blog/2019-10-scheduler.

تخم ریزی

هنگامی که می خواهید یک وظیفه را به زمان اجرا ارسال کنید تا توسط یک پردازنده اجرا شود، شما spawn آی تی. با توکیو می توان به آن دست یافت tokio::spawn عملکرد.

مثلا:
ch_03/tricoder/src/ports.rs

tokio::spawn(async move {
    for port in MOST_COMMON_PORTS_100 {
        let _ = input_tx.send(*port).await;
    }
});

این قطعه کد 1 وظیفه ایجاد می کند که در صف یکی از پردازنده ها قرار می گیرد. از آنجایی که هر پردازنده رشته سیستم عامل خود را دارد، با ایجاد یک کار، ما از تمام منابع دستگاه خود بدون نیاز به مدیریت رشته ها استفاده می کنیم. بدون تخم ریزی، تمام عملیات بر روی یک پردازنده و در نتیجه همان رشته اجرا می شود.

برای مقایسه، در Go ما از عبارت استفاده می کنیم go کلمه کلیدی برای ایجاد یک کار (به نام گوروتین):

go doSomething()

1 ایمیل در هفته برای یادگیری نحوه (سو) استفاده از فناوری برای سرگرمی و سود: برنامه نویسی، هک و کارآفرینی.


من حتی بیشتر از شما از اسپم متنفرم. من هرگز ایمیل شما را به اشتراک نمی گذارم، و شما می توانید در هر زمانی اشتراک خود را لغو کنید.

از مسدود کردن حلقه های رویداد خودداری کنید

این مهم ترین چیزی است که باید به خاطر بسپارید.

مهمترین قانونی که در دنیای آن باید به خاطر بسپارید async-await است برای مسدود کردن حلقه رویداد.

چه مفهومی داره؟ عدم فراخوانی توابعی که ممکن است بیشتر از آن اجرا شوند 10 تا 100 میکروثانیه به طور مستقیم. بجای، spawn_blocking آنها

عملیات فشرده CPU

بنابراین، چگونه می توان عملیات محاسباتی فشرده، مانند رمزگذاری، رمزگذاری تصویر، یا هش فایل را اجرا کرد؟

tokio را فراهم می کند tokio::task::spawn_blocking عملکردی برای مسدود کردن عملیاتی که در نهایت خود به خود تمام می شوند. منظور من یک عملیات مسدود کردن است که یک کار پس زمینه بی نهایت نیست. برای این نوع کار، یک زنگ نخ مناسب تر است.

در اینجا یک مثال از یک برنامه کاربردی است که در آن spawn_blocking استفاده می شود:

let is_code_valid = spawn_blocking(move || crypto::verify_password(&code, &code_hash)).await?;

در واقع، عملکرد crypto::verify_password انتظار می رود صدها میلی ثانیه طول بکشد تا تکمیل شود، حلقه رویداد را مسدود می کند.

در عوض، با تماس spawn_blocking، عملیات به مجموعه موضوعات مسدود کننده توکیو ارسال می شود.

استخرهای نخ مختلف توکیو

زیر کاپوت، توکیو دو استخر نخ را نگه می دارد.

یک thread pool با اندازه ثابت برای مجریان آن (حلقه‌های رویداد، پردازنده‌ها) که وظایف ناهمگام را اجرا می‌کنند. وظایف Async را می‌توان با استفاده از این مجموعه موضوعی ارسال کرد tokio::spawn.

و یک مخزن نخ با اندازه پویا اما محدود (از نظر اندازه) برای مسدود کردن وظایف. به طور پیش فرض، دومی تا 512 رشته رشد می کند. این مجموعه موضوعات بسته به تعداد کارهای مسدودکننده در حال اجرا، مقیاس بزرگ و پایین می‌یابد. کارهای مسدود کردن را می توان با استفاده از این موضوع ارسال کرد tokio::task::spawn_blocking. می توانید در مورد نحوه پیکربندی دقیق آن بیشتر بخوانید در مستندات توکیو.

به این دلیل async-await همچنین به عنوان “نخ های سبز” یا “نخ های M:N” شناخته می شود. آنها برای کاربر (برنامه نویس) مانند رشته به نظر می رسند، اما spawning ارزان‌تر است، و می‌توانید رشته‌های سبز رنگ بیشتری نسبت به تعداد واقعی رشته‌های سیستم‌عاملی که زمان اجرا در زیر هود استفاده می‌کند، ایجاد کنید.

آیا می خواهید در مورد زنگ و امنیت بیشتر بدانید؟ کتاب زنگ کلاه سیاه من را دریافت کنید.

لینک منبع

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.