همزمانی بدون ترس
رسیدگی ایمن و کارآمد به برنامهنویسی همزمان یکی دیگر از اهداف اصلی Rust است. برنامهنویسی همزمان (concurrent programming)، که در آن بخشهای مختلفی از یک برنامه بهطور مستقل اجرا میشوند، و برنامهنویسی موازی (parallel programming)، که در آن بخشهای مختلفی از برنامه بهطور همزمان اجرا میشوند، با توجه به استفادهی روزافزون کامپیوترها از پردازندههای چندهستهای، بهطور فزایندهای اهمیت یافتهاند. بهصورت تاریخی، برنامهنویسی در این زمینهها دشوار و مستعد خطا بوده است. Rust امیدوار است این وضعیت را تغییر دهد.
در ابتدا، تیم Rust گمان میکرد که اطمینان از ایمنی حافظه و جلوگیری از مشکلات همزمانی دو چالش مجزا هستند که باید با روشهای متفاوتی حل شوند. با گذشت زمان، این تیم دریافت که سیستم مالکیت و سیستم نوعها در Rust مجموعهای قدرتمند از ابزارها هستند که میتوانند هم برای مدیریت ایمنی حافظه و هم برای حل مشکلات همزمانی مفید باشند! با بهرهگیری از مالکیت و بررسی نوعها، بسیاری از خطاهای همزمانی در Rust به جای آنکه خطاهایی در زمان اجرا باشند، در زمان کامپایل شناسایی میشوند. بنابراین، بهجای صرف زمان زیاد برای بازتولید شرایط دقیق بروز یک باگ همزمانی در زمان اجرا، کد نادرست اصلاً کامپایل نخواهد شد و خطایی با توضیح مشکل به شما نمایش داده میشود. در نتیجه، شما میتوانید کد خود را همان موقع که روی آن کار میکنید اصلاح کنید، نه احتمالاً پس از آنکه به مرحلهی تولید رسیده است. ما این ویژگی Rust را با لقب همزمانی بیباکانه (fearless concurrency) توصیف کردهایم. همزمانی بیباکانه به شما این امکان را میدهد که کدی بدون باگهای ظریف بنویسید و آن را بدون ایجاد باگهای جدید، بهراحتی بازسازی (refactor) کنید.
توجه: برای سادگی، ما بسیاری از مشکلات را همزمانی مینامیم، بهجای آنکه دقیقتر بگوییم همزمانی و/یا موازی بودن. لطفاً در این فصل، هرجا واژهی همزمانی را دیدید، در ذهن خود آن را به همزمانی و/یا موازی بودن تعبیر کنید. در فصل بعد، که این تمایز اهمیت بیشتری دارد، بهطور دقیقتر به موضوع خواهیم پرداخت.
بسیاری از زبانهای برنامهنویسی در راهحلهایی که برای حل مشکلات همزمانی ارائه میدهند، دچار تعصباند. بهعنوان مثال، زبان Erlang امکاناتی بسیار زیبا برای همزمانی مبتنی بر ارسال پیام ارائه میدهد، اما روشهای آن برای اشتراکگذاری وضعیت بین تردها بسیار پیچیده است. پشتیبانی صرفاً از یک زیرمجموعه از راهحلهای ممکن، راهبردی منطقی برای زبانهای سطحبالاست؛ چراکه این زبانها با واگذاری بخشی از کنترل، در ازای انتزاعهای بیشتر، مزایایی ارائه میدهند. با این حال، از زبانهای سطح پایین انتظار میرود که در هر موقعیت، بهترین عملکرد را ارائه دهند و انتزاعهای کمتری از سختافزار داشته باشند. بنابراین، Rust مجموعهای متنوع از ابزارها را برای مدلسازی مسائل در اختیار شما قرار میدهد تا متناسب با وضعیت و نیازمندیهای شما، راهحل مناسب را انتخاب کنید.
موضوعاتی که در این فصل پوشش خواهیم داد عبارتاند از:
- نحوه ایجاد نخها برای اجرای همزمان چندین بخش از کد
- همزمانی پیامرسانی، جایی که کانالها پیامها را بین نخها ارسال میکنند
- همزمانی حالت اشتراکی، جایی که چندین نخ به بخشی از داده دسترسی دارند
- صفات
Sync
وSend
، که تضمینهای همزمانی Rust را به انواع تعریفشده توسط کاربر و همچنین انواع ارائهشده توسط کتابخانه استاندارد گسترش میدهند