سیستم‌عامل به‌هنگام
سیستم عامل‌های بهنگام سیستم عامل‌هایی هستند که برای پردازش پردازه‌های به هنگام زمانی که داده‌ها فراخوانی می‌شوند است، که تاخیرهای میانگیرها را ندارد. نیازمندی زمان پردازش بر حسب دهم ثانیه یا کمتر محاسبه می‌شود. آن‌ها به صورت رویداد محور هستند یا به صورت اشتراک زمانی. سیستم‌های اشتراک زمانی بین کارها بر اساس اولویت آن‌ها گزینش می‌کنند و سیستم‌های اشتراک زمانی بین کارها بر اساس وقفه‌ها گزینش می‌کنند.
ویژگی کلیدی سیستم عامل‌های به هنگام سطح سازگاری آن با مقدار زمان مورد نیاز برای تأیید و پردازش کامل کار یک برنامه است. هدف اصلی طراحی پردازش پهنای زیاد داده نیست بلکه تضمین یک عملکرد ملایم یا سخت است. یک سیستم عامل به هنگام ملایم عموماً زمان تعیین شده اتمام را برآورده می‌کند، ولی اگر به‌طور قطعی زمان تعیین شده اتمام را برآورده کند این سیستم یک سیستم سخت است.
یک سیستم عامل به هنگام ملایم الگوریتم پیشرفته‌ای برای زمان‌بندی دارد. انعطاف‌پذیری در زمان‌بندی قابلیت وسیع تری در اولویت بندی پردازه‌ها فراهم می‌کند، ولی یک سیستم عامل به هنگام مختص بازه کمتری از برنامه‌ها است. ویژگی اصلی سیستم عامل به هنگام حداقل بودن تأخیر وقفه‌ها و گزینش در ریسه‌ها است. سیستم عامل‌های به هنگام از روی میزان سرعت یه میزان قابل پیش‌بینی بودن پاسخ گویی سنجیده می‌شوند تا حجمی از کار که می‌توانند در یک بازهٔ زمانی انجام دهند
طراحی‌های متداول عبارتند از: سیستم اشتراک زمانی بیشتر از مقدار مورد نیاز گزینش کارها را انجام می‌دهد، ولی قابلیت بهتری برای اجرای موازی چندین کار را فراهم می‌کند با این فرض که کاربر فقط از یک دستگاه استفاده می‌کند. پردازنده‌های قدیمی تعداد زیادی سیکل برای گزینش کارها نیاز داشتند، برای همین پردازنده کار مفیدی نمی‌توانست انجام دهد. برای مثال، پردازندهٔ ۶۸۰۰۰ موتورولا با سرعت ۲۰ مگا هرتز، در بهترین حالت ۲۰ میکرو ثانیه زمان برای گزینش کار مصرف می‌کرد ولی پردازندهٔ ARM با سرعت ۱۰۰ مگا هرتز گزینش کار را در کمتر از ۳ میکرو ثانیه انجام می‌داد. برای همین سیستم عامل‌های قدیمی سعی می‌کردند تا زمان کمتری را صرف گزینش کارها کنند.
به صورت معمول، یک پردازه سه حالت داشت: بیشتر پردازه‌ها در حالت آماده یا مسدود قرار دارد چون در هر زمان فقط یک پردازه می‌تواند در پردازنده در حال اجرا باشد. تعداد پردازه‌ها در صف اماده‌ها می‌تواند متفاوت باشد و بستگی به تعداد پردازه‌هایی که سیستم می‌خواهد که انجام شوند و نوع زمان‌بندی ای که سیستم استفاده می‌کند دارد. در یک سیستم غیر پیشگیرانه و با قابلیت پردازش چند وظیفه‌ای، پک پردازه باید از وقت اجری خود برای بقیه پردازه‌ها صرف نظر کند که باعث می‌شود تعداد بسیار زیادی پردازه در صف اماده‌ها قرار گیرند. به‌طور معمول داده ساختار صف اماده‌ها در سیستم زمان‌بندی برای کم کردن زمان صرف شده در قسمت بحرانی زمان‌بندی در بدترین حالت طراحی شده‌است که در این صورت قابلیت پیشگیرانه ممنوع شده و در بعضی موارد تمام وقفه‌ها از کار می‌افتند؛ ولی انتخاب داده ساختار به بیشترین تعداد پردازه‌ها که می‌تواند در صف آماده باشد نیز بستگی دارد. اگر تعداد زیادی پردازه در صف قرار نگیرد در این صورت یک لیست پیوندی دو طرفه انتخاب بهینه‌ای است. اگر لیست بعضی وقت‌ها تعداد زیاده پردازه را در خود نگه می‌دارد در این صورت این لیست باید بر اساس اولویت مرتب شود که باعث می‌شود برای پیدا کردن پردازه با بالاترین اولویت لازم نیست کل لیست را پیمایش کنیم ولی برای درج پردازه در این لیست لازم است کل لیست را پیمایش کنیم تا جای مناسب را برای پردازه پیدا کنیم. باید مراقب باشیم تا قابلیت پیشگیری را در طول زمان این جستجو ممنوع نکنیم. محدوده‌های بحرانی بزرگ باید به قسمت‌های کوچکتر تقسیم شوند. اگر در حین درج یک پردازه با اولویت پایین، با وقوع یک وقفه پردازه‌ای با اولویت بالا را بخواهیم درج کنیم، پردازه با اولویت بالا می‌تواند درج شود و اجرا شود سپس پردازه با اولویت پایین درج شود. زمان بحرانی پاسخ دهی مقدار زمانی است که طول می‌کشد تا یک پردازهٔ جدید در صف درج شود و پردازه با بالاترین اولویت به حالت اجرا برگردد. یک سیستم عامل به هنگام با طراحی خوب درج در صف را با ۳ الی ۲۰ دستور انجام می‌دهد و بازگرداندن پردازه با بالاترین اولویت به حالت اجرا را در ۵ الی ۳۰ دستور انجام می‌دهد. در سیستم‌های پیچیده‌تر، کارهای به هنگام منابعشان را با پردازه‌های غیر به هنگام به استراک می‌گزارند، و صف اماده‌ها می‌تواند طل دلخواه داشته باشد. در این سیستم‌ها استفاده از لیست پیوندی کاری نا مساعد است.
یک سیستم چند وظیفه‌ای مثل یونیکسدر پردازش به هنگام ضعیف است، چون اولویت بالاتر به پردازه‌ای داده می‌شود که کمترین منابع را درخواست کند، برای همین نمی‌توان اطمینان داشت که پردازه‌ای با زمان اجرای بحرانی به منابع کافی دست میابد. سیستم‌های چند وظیفه‌ای باید اشتراک داده‌ها و منابع سخت‌افزاری را مدیریت کنند. معمولاً نا امن است که دو پردازه به‌طور هم‌زمان به یک داده یا منابع سخت‌افزاری دسترسی پیدا کنند، معمولاً ۳ روش وجود دارد تا این مشکل حل شود:
سیستم عامل‌های عام منظوره معمولاً به کاربران اجازه نمی‌دهند تا وقفه‌ها را غیرفعال کنند، چون برنامه‌ای که کاربر ان را نوشته نمی‌تواند پردازنده را تا هر زمانی که بخواهد دست خود بگیرد. بعضی از پردازنده‌های جدید نیز اجازه نمی‌دهد تا برنامهٔ سطح کاربر وقفه‌ها را غیرفعال کند به این خاطر که این قابلیت یک ویژگی کلیدی سیستم عامل محسوب می‌شود. با این حال تعداد زیادی از سیستم عامل ای به هنگام و سیستم‌های نهفته، اجازه این را می‌دهند تا برنامه‌ها در سطح هسته اجرا شوند تا فراخوان سیستمی بهینه تری داشته باشد و کنترل بیشتری روی محیط اجرایی بدون مداخله سیستم عامل داشته با شد. در سیستم‌های تک پردازنده‌ای، برنامه‌ای که در سطح هسته اجرا می‌شود و وقفه‌ها را غیرفعال می‌کند کمترین سربار را برای دسترسی هم‌زمان به منابع مشترک دارد. در این حال که وقفه‌ها غیر فعالند و فرا خوانی متوقف شونده انجام ندهد پردازهٔ فعلی از پردازنده به صورت انحصاری استفاده می‌کند چون هیچ پردازهٔ دیگر یا وقفه‌ای نمی‌تواند کنترل را بدست بگیرد، پس محدودهٔ بحرانی در امان است. وقتی که پردازه از محدوده بحرانی خارج می‌شود باید وقفه‌ها را فعال کند، وقفه‌های در حال انتظار بعد از ان اجرا می‌شود. متوقف کردن وقفه‌ها باید زمانی انجام شود که طولانی‌ترین مسیر محدودهٔ بحرانی کمتر از بزرگترین مسیر پیش‌فرض باشد. معمولاً این متود محافظت زمانی استفاده می‌شود که محدودهٔ بحرانی دارای تعداد کمی دستور است و هیچ حلقه‌ای ندارد.
وقتی که منابع مشترک باید بدون مسدود کردن بقیهٔ پردازه‌ها تخصیص شود، بهتر است از مکانیزم‌هایی که در سیستم عامل‌های عام منظوره نیز وجود دارد استفاده کنیم مانند سمافورها و سیستم‌های پیغام‌رسانی بین پردازه‌ای که توسط سیستم عامل نظارت می‌شود. چنین مکانیزم‌هایی معمولاً از فراخوان‌ها سیستمی استاده می‌کنند، و معمولاً موقع خروج کد اعزام‌کنندهٔ سیستم عامل را صدا می‌زنند، بنابراین آن‌ها به اندازه صدها دستور زمان نی برند ا اجرا شوند، در صورتی که غیرفعال کردن وقفه‌ها تعداد خیلی کمی دستور نیاز دارد. یک سمافور دودویی یا قفل است یا باز. وقتی که قفل است، پردازه‌ها باید صبر کنند تا باز شود. پس یک سمافور دودویی مانند یک انحصار متقابل است. یک پردازه معمولاً یک مهلت برای صبر کردن برای سمافور تعیین می‌کند. تعدادی مشکل معروف در مورد سمافورها وجود دارد مانند بن‌بست‌ها و معکوس کردن اولویت‌ها در معکوس کردن اولویت‌ها یک پردازه با اولویت بالا در انتظار پردازه‌ای با اولویت پایین که سمافور را در دست دارد است، ولی پردازه با اولویت پایین زمان کا فی برای اتمام کار خود ندارد. یک روش ساده این است که پردازهای که سافور را در دست دارد بالاترین اولویت را داشته باشد. این روش ساده وقتی شکست می‌خورد که چند سطح از انتظار داشته باشیم: پردازهٔ "الف" منتظر پردازهٔ "ب " است که سمافر را در دست دارد و پردازهٔ "ب" منتظر پردازهٔ "پ" است. رسیدگی به وراثت چند سطحی بدون در نظر گرفتن بی‌ثباتی در حلقه‌ها بسیار پیچیده و مشکل‌زا است. در بن‌بست دو یا چند پردازه سمافورها را بدون مهلت قفل کرده و تا ابد برای سمافورهای پردازه‌های یک صبر می‌کنند، که باعث ایجاد یک وابستگی حلقه‌ای می‌شود. از بن‌بست با طراحی دقیق سمافورها یا استفاده از سمافورهای شکست پذیر که کنترل سمافور را به پردازه‌ها با اولویت بالاتر در شرایط تعیین شده می‌دهد می‌توان جلوگیری کرد.
یک روش دیگر برای استفاده از منابع مشترک این است که پردازه‌ها در یک شمای سازمان دهی شده تبادل پیام یام‌های خود را بفرستند. در این روش یک منبع دقیقاً توسط یک پردازه مدیریت می‌شود. وقتی یک پردازهٔ دیگر بخواهد ان منبع را تغییر دهد یک پیغام به پردازهٔ مدیر می‌فرستد. با اینکه این سیستم در کارهای به هنگام از سمافورها ضعیف تر است، این سیستم سادهٔ پیام‌رسانی بیشتر مشکلات بن‌بست‌ها را ندارد و معمولاً خوش رفتارتر هستند. با این حال مشکلاتی نظیر مشکلات سمافور ممکن است اتفاق بیفتد. معکوس کردن اولویت‌ها وقتی اتفاق می‌افتد که یک پردازه در حال اجرای پیغام با اولویت پایین است و پیغام با اولویت بالا را در صف پیغام‌ها نادید می‌گیرد. بن‌بست نیز زمانی اتفاق می‌افتد که یا چند پردازه منتظر جوا همدیگر هستند.
با توجه به اینکه سیستم رسیدگی به وقفه‌ها یک پردازه ا اولویت بالا و در حال اجرا را مسدود می‌کنند و با توجه به اینکه سیستم عامل‌های به هنگام طراحی شده‌اند تا تأخیر ریسه‌ها را به کمینه‌ترین حالت برساند سیستم رسیدگی به وقفه در کوچک‌ترین حالت ساخته می‌شود. تنها چیزی که لازم است تأیید وقفه یا غیرفعال کردن ان یا اطلاع‌رسانی به پردازه تا تا بدانند که کار باید حتماً انجام شود است. یک سیستم عامل دارای کاتالوگی از شی‌هایی است که آن‌ها را مدیریت می‌کند مانند ریسه‌ها انحصارهای متقابل، حافظه و غیره. بروز رسانی‌های این کاتالوگ باید کنترل شده با شد. به همین دلیل می‌تواند مشکل ساز باشد وقتی که سیستم رسیدگی به وقفه‌ها یک تابع سیستم عامل را فراخوانی می‌کند در حالی که یک برنامه دیگر در حال اجرا کردن ان است. تابع فراخوانی شده توسط سیستم رسیدگی به وقفه‌ها ممکن است تابع را در حالت ناسازگار یابد چون ان برنامه در حال به روزرسانی است. دو روش برای برطرف کردن این مشکل وجود دارد. معماری متحد و و معماری قطعه قطعه شده. سیستم عامل‌های به هنگام که از معماری متحد استفاده می‌کنند این مشکل را با غیرفعال کردن وقفه‌ها در زمانی که کاتالوگ در حال بروزرسانی است انجام می‌دهند. مشکل این کار ین است که تأخیر وقفه‌ها بالا رفته و امکان از دست رفتن وقفه‌ها وجود دارد. معماری قطعه قطعه شده مستقیماً سیستم عامل را فراخوانی نمی‌کند بلکه کارهای مربوط به سیستم عامل را به یک سیستم رسیدگی دیگر می‌سپارد. این سیستم رسیدگی اولویت بالاتری نسبت به ریسه‌ها دارد ولی اولویت ان از سیستم رسیدگی به وقفه‌ها پایین‌تر است. مزیت این معماری این است که تعداد کمی سیکل به تأخیر وقفه اضافه می‌شود. در نتیجه، سیستمم عامل‌هایی که معماری قطعه قطعه استفاده می‌کنند قابل پیش‌بینی ترند و با نرخ بیشتری از وقفه‌ها می‌توانند سر و کار داشته باشد در مقایسه با معماری متحد.
تخصیص حافظه در سیستم عامل‌های به هنگام مهم تر از سیستم عامل‌های دیگر است. اولاً، برای ثبات نباید کمبود حافظه داشته باشیم (حافظه‌ای که تخصیص شده باشد ولی هرگز آزاد نشود). این دستگاه باید بی پایان کار کند، هرگز نیاز به راه اندازی مجدد نداشته باشد. به همین دلیل، تخصیص پویای حافظه ابداع شد. هر وقت ممکن بود، تمام حافظهٔ مورد نیاز به صورت ایستا در زمان کامپایل مشخص شده‌است. دلیل دیگر برای اجتناب کردن از تخصیص پویای حافظه تکه‌تکه شدن حافظه است. با تخصیص‌های مکرر و آزاد کردن قسمت‌های کوچکی از حافظه، ممکن است وضعیتی پیش بیاید که حافظه به چند قسمت تقسیم می‌شود، که درین صورت سیستم عامل نمی‌تواند یک بلاک بزرگ متوالی تخصیص دهد، گرچه حافظهٔ کافی داریم. ثانیاً سرعت تخصیص مهم است. یک شمای استاندارد تخصیص حافظه یک لیست پیوندی نامشخص را پیمایش می‌کند تا یک بلاک مناسب پیدا کند؛ که در سیستم‌های به هنگام قابل قبول نیست زیرا تخصیص حافظه باید در یک زمان مشخص اتفاق بیفتد. الگوریتم سادهٔ بلاک با سایز ثابت بسیار خوب در سیستم‌های ساده نهفته کار می‌کند به دلیل سربار کمی که دارد