چند برنامگی
مقدمه ای به سیستم های عامل
در پروژه بعدی شما پشتیبانی مناسب برای چند برنامه نویسی را طراحی و اجرا خواهید کرد. شما فرمان های سیستم را طوری توسعه خواهید داد که اصول ارتباط درون فرایندی و مدیریت فرایند را انجام دهد. شما این را به پروژه اول دارای کد می افزایید. اطمینان حاصل که قبل از شروع پروژه دوم تمام نواقص در پروژه اول را اصلاح کرده اید. این راه حل برای پروژه یک به عنوان بخشی از جلسه هفته بعد مورد بررسی قرار خواهد گرفت.
ناکوس در حال حاضر یک محیط تک برنامه نویسی است. ما مجبوریم ناکوس را تغییر دهیم به طوری که هر فرایند در مسیر سیستم خود حفظ شوند. ما باید تخصیص حافظه و واپس گیری آن توجه داشته باشیم. هم چنین تمام داده ها و وابستگی های همزمان سازی بین رشته ها را مد نظر قرار می دهیم. شما ابتدا قبل از کد گذاری راه حل را طراحی میکنید جزئیات در زیر آورد است:
1- استثنائات کلی (استثنائات تماس غیر سیستمی) برای به اتمام رساندن رشته به جای متوقف کردن سیستم را تغییر دهید. این کار مهم خواهد بود زیرا یک استثنای زمان اجرا نباید باعث شود که سیستم عامل خاموش شود. قبل از تکمیل پروژه احتمالاًمجبور خواهید بود که چندین بار به این کد سر بزنید. چند موضوع مربوط به همزمان سازی وجود دارد که باید در طی خروج از رشته به آن ها بپردازید.
2- چند برنامه نویسی را اجرا کنید. کدی که به شما داده ایم محدود به اجرای یک برنامه کاربرد در هر بار می باشد. برای تغییر سیستم از تک برنامه نویسی به چند برنامه نویسی باید چند تغییر در addrspace.h و addrspace.cc انجام دهید. باید کارهای زیر را انجام دهید: الف) به شیوه ای برای تخصیص فریم های حافظه فیزیکی برسید به طوری که چندین برنامه را بتوان به یکباره در حافظه بارگذاری کرد.
ب) شیوه ای برای کپی کردن داده ها به هسته یا از هسته و از فضای آدرس مجازی کاربر یا به آن فراهم کنید.
ج) وقتی یک برنامه کاربر پایان مییابد به طور مناسبآزادسازی فضای آدرس انجام شود.
د) تغییر الگوریتم بارگذار برنامه کاربر به طوری که فریم های اطلاعاتی را جابجا کند بسیار مهم است. در حال حاضر تخصیص فضای حافظه با این فرض است که یک فرایند در یک بخش مجاور حافظه بارگذاری شده است. وقتی چند برنامه نویسی فعال شد، حافظه دیگر ماهیتاً مجاور محسوب نمی شود اگر برنامه را اصلاح نکنید احتمال دارد که بارگذاری دیگر برنامه کاربر سیستم عامل را خراب کند.
3- فرمان سیستم space id exec (char*name) را اجرا کنید. Exec یک برنامه کاربر جدید مشخص شده در نام پارامتر، اجرا شده در درون یک رشته سیستم جدید را شروع می کند. شما باید کارکرد start process در progtest.cc را بررسی کنید تا دریابید که چگونه فضای کاربر در درون یک رشته سیستم را ایجاد کنید. Exec باید در هنگام خطا 1- را برگرداند در غیر این صورت باید "process space id" برنامه سطح کاربری که ایجاد کرده است را برگرداند (نکته: space id ها می تواند به شیوه ای مشابه با open file id های پروژه 1 شما پیگیری شود با این استثنا که ممکن است بخواهید در خارج از رشته ان ها را دنبال کنید).
4- فرمان های سیستم int join (space ID id) و void exit (int exit code) را اجرا کنید. Join آن طور که در پارامتر آن ذکر شده است منتظر مانده و یک process space id را مسدود می کند. exit یک خروج را بر هر کسی که کار اتصال انجام می دهد بر می گرداند اگر یک برنامه به طور موفقیت آمیزی تکمیل شود کد خروج صفر است و اگر خطا وجود داشته باشد مقدار دیگری می شود. پارامتر کد خروج از طریق پارامتر exit code تعیین می شود. اگر اتصال با خطا مواجه شود join کد خروج برای فرایندی که مسدود می کند را 1- تعیین می کند. یک برنامه کاربر فقط می تواند به فرایندهایی بپیوندند که به طور مستقیم به وسیله فرمان سیستم exec ایجاد شده باشد. می توانید به فرایندهای دیگر یا به خودتان متصل شوید. شما مجبور خواهید بود تا از راهنماهای درون فرمان های سیستم خود برای هماهنگ کردن فرایندهای کاربر joining و exiting استفاده کنید. مشاهده خواهید کرد که این را می توان به عنوان ویرایشگر ساکنipc (ارتباط درون فرایندی) الگوسازی کرد.
5- فرمان سیستم int creates semaphore (char*name, int semval) را اجرا کنید. از فرمان سیستم حذف که در پروژه اجرا کرده اید درخواهید یافت که ما مجبور خواهیم بود تا start.c و syscall.h را روزامد کنیم تا امضاهای فرمان سیستم جدید بیفزاییم. شما یک ظرف در سطح سیستم ایجاد خواهید کرد که می تواند تا 10 راهنمای نام گذاری شده را در خود جای بدهد. در هنگام موفقیت سیستم create semaphore عدد صفر و در هنگام خطا عدد 1- را بر می گرداند. اگر نقاط آزاد کافی در ظرف وجود نداشته باشد فرمان سیستم create semaphore خطا خواهد شد، نام تهی بوده و یا مقدار اولیه راهنما کمتر از صفر می باشد.
6- فرمان های سیستم int wait (char *name) و int signal (char *name) را اجرا کنید. پارامتر اسم نام راهنما می باشد. هردو فرمان سیستم در هنگام موفقیت صفر و در هنگام خطا 1- را بر می گرداند. اگر کاربر یک نام راهنما غیر قانونی (نامی که ایجاد نشده است) را بدهد خطا می تواند اتفاق بیفتد.
7- یک برنامه واسطه ساده برای امتحان فرمان های سیستم جدید اجرا شده به صورت بالا را اجرا کنید. برنامه واسطه باید در هر بار یک دستور بگیرد و برنامه کاربرمناسب را اجرا کند. برنامه واسطه باید در هر برنامه “exec”ed را متصل کند و منتظر خروج برنامه بماند. در هنگام برگشت از join ، کد خروج را در صورتیکه غیر صفر باشد (اجرای طبیعی) چاپ کنید. هم چنین برنامه واسطه را طوری طراحی کنید که بتواند در پس زمینه برنامه اجرا کند. هر دستور شروع شده با کاراکتر (&) باید در پس زمینه اجرا شود.
8- یک راه حل سطح کاربر برای مشکل تولید کننده / مصرف کننده ایجاد کنید. راه حل باید از سه برنامه تشکیل شده باشد: یک برنامه شروع سطح اصلی، تولید کنندگان و مصرف کنندگان. برنامه شروع سطح اصلی باید به صورت حداقل کاربر برای تعداد تولید کنندگان برای "exec" و تعداد مصرفکنندگان "exec" و همچنین یک شمارش تکرار برای تولید کنندگان و مصرف کنندگان و اندازه بافر محدود را ترغیب کند. برنامه شروع اصلی سپس تولید کنندگان ومصف کنندگان را exec می کند و منتظر می ماند تا زمانی که تمام فرایندها تکمیل شود. هر تولید کننده باید یک بار مفید کاراکتر منحصر به فرد ایجاد کند (مثال: تولید کننده یک a را تولید میکند و تولید کننده دو b را تولید می کند). تولید کنندگان و مصرف کنندگان باید تکرارها را در یک فرمت خلاصه وشفاف چاپ کنند. توجه داشته باشید که exec اجازه مباحث خط فرمان را نمی دهد. شما می توانید از فایل از پروژه یک به عنوان بافر مشترک برای توجه به این مشکل استفاده کنید.
9- دو برنامه کاربر به جز اقلام هفت و هشت طراحی کنید که بالاتر ازآن بتواند در داخل برنامه واسطه اجرا شود تا قوی بودن راه حل کلی پروژه شما را نشان دهد.
10- مستندسازی (10 درصد) شامل مستند سازی داخلی و مستند سازی خارجی طبق آن چه که در پروژه یک توصیف شده است می باشد. یک فایل reade ایجاد کنید و آن را در دایرکتوری کد قرار دهید. کد خود را tar کنیدو آن را به عنوان یک فایل ارایه کنید. راهنمایی های ارایه شده در پروژه یک را دنبال کنید. ما در نظر داریم نرم افزار آشکار ساز سرقت اتوماتیک را برای اشکار کردن هر گونه پروژه کپی شده اجرا کنیم. پیامدها معمولا برای کسانی که در صداقت اکادمیک ندارند نامطلوب می باشد بنابراین به تنهایی کار کنید و نه به صورت گروه. این پروژه گروهی نیست پروژه های دیرتر از موعد پذیرفته نمی شود. مستند سازی خارجی حاوی طرح نشان داده شده به وسیله یک نمودار کلاسی آنلاین را در تاریخ مقرر ارایه کنید وقتی نمونه نمایشی خود را انجام دادید یک کپی سخت به همراه خود به TA بیاورید.
چند وظیفه ای
توانایی اجرای بیش از یک وظیفه به صورت همزمان را گویند که این وظیفه یک برنامه است. عبارت های چند وظیفه ای و چند پردازی اغلب به جای هم استفاده می وشند اگر چه چند پردازی حاکی از ان است که بیش از یک سی پی یو نقش دارد. در چند وظیفه ای، تنها یک سی پی یو نقش دارد اما با چنان سرعتی از یک برنامه به برنامه دیگر تغییر می کند که این گونه به نظر می رسد که تمام برنامه ها به طور همزمان اجرا می شوند.
دو نوع اصلی چندوظیفهای وجود دارد: انحصاری و مشارکتی. در چند وظیفهای انحصاری، سیستم عامل برش های زمانی سی پی یو را به هر برنامه را به صورت بسته ای ارسال می کند. در چند وظیفه ای مشارکتی هر برنامه می تواند سی پی یو را تا زمانی که نیاز دارد کنترل کند. با این حال اگر یک برنامه از سی پی یو استفاده نمی کند می تواند به برنامه دیگری اجازه دهد به طورموقت ازآن استفاده کند. OS/2 ، ویندوز 95 ، ویندوز NT و سیستم عامل امیگا و یونیکس از چند وظیفه ای انحصاری استفاده می کنند در حالی که میکروسافت ویندوز و مولتی فایندر (برای کامپیوترهایمکین تاش) از چندوظیفهای مشارکتی استفاده می کنند.
سیستم های عامل چند برنامه ای / چند وظیفه ای
در ابتدا کاربران از این تسهیلات برنامه واحد راضی بودند اما با ایجاد سی پی یوها قوی تر، حافظه بیشتر و دیسک درایورها بزرگ و ارزان سیستم های عاملی ایجاد شده اند که اجازه می دهند که بیشتر از یک برنامه یا وظیفه به طور همزمان اجرا شود. این را چند وظیفه ای یا چند برنامه ای گویند. یک پردازشگر واحد نمی تواند بیش از یک وظیفه را به طور همزمان پردازش کند. فقط ظاهراَ این گونه است. گاهی اوقات این را پردازش همزمان یا متقارن گویند. سیستم عامل ویندوز این کار را با دادن بخش انحصاری حافظه به هر برنامه و حافظه مشترک برای کات کردن و پیست کردن بین برنامه های کاربردی انجام می دهد. به هر وظیفه می شود بخش خاصی از زمان سی پی یو را اختصاص داد (که به آن تقسیم زمان گفته می شود) و معمولا هر وظیفه به عنوان یک وظیفه با گردش نوبت اجرا خواهد شد که در آن هر وظیفه به نوبت خدمات رسانی می شود. در این جا یک مقایسه با معلمی وجود دارد که تلاش می کند به چندین سوال دانش اموزان با دادن یک برش زمانی به هر سوال و سپس رفتن به سوال بعد پاسخ دهد. اگر تعدادی از سوالات در مقدار زمان موجود پاسخ نداده شود به صورت تعلیق درآمده و سپس وقتی که مجددا نوبت به دانش آموز رسید به آن ها پاسخ داده می شود. در موقعیت کامپیوتر هر وظیفه به نوبت انجام می شود تا زمانی که وظیفه آخر پردازش شده و سپس کل فرایند شروع شود.
در مثال بالا یک وظیفه در صف پردازشگر وارد می شود و اگر قابل اجرا باشد در زمانی که برش زمانی آن ظاهر می شود به پردازشگر داده می شود. در این مرحله سه پیامد ممکن وجود دارد:
می تواند پایان یابد
زمان پردازشگر به پایان می رسد و به صف بر می گردد تا منتظر نوبت خود شود.
به زبان I/O نیاز دارد وقتی این اتفاق می افتد به صف I/O که در ان منتظر ابزار می ماند تا آزاد شود.
مشکلات عمده مربوط به سیستم های چند وظیفه ای به شرح زیر می باشد:
اگر یک وظیفه قرار باشد که هر بار به آن نیاز باشد مجددا بارگذاری شود احتمالا برش زمانی آن به پایان می رسد. با قرار دادن هسته برنامه در حافظه مقداری پردازش می توان اتفاق بیفتد. کارامدترین سیستم های چند وظیفه ای نیاز به حافظه زیادی برای کار موثر دارند. اگر وظایف زیادی شروع شود سیستم تا حد یک سرعت قابل قبول کند می شود.
در ساده ترین شکل به دو وظیفه پنجاه درصد زمان سی پی یو داده می شود. متاسفانه سیستم عامل نیز به مقدار زمان سی پی یو نیاز دارد و با افزایش لیست وظیفه این زمان افزایش می یابد. به تدریج سیستم به حالت توقف می رسد.
برنامه های بزرگ باید مقداری اطلاعات ذخیره شده در دیسک داشته باشند و بازیابی زمان بر است.
تکنیک معمول برای پرداختن به این مشکل تجزیه برنامه ها به صفحات داده است. مکررترین صفحه استفاده شده در حافظه به جا می ماند و فقط وقتی برنامه تلاش می کند تا به صفحه ای دست پیدا کند که در حافظه وجود ندارد، سیستم عامل صفحه مناسب را خواهد آورد. در برنامه های بزرگ یا نامناسب هنوز می تواند زمان افزایش پیدا کند و منجر به شکل گیری ایده ای به نام فعالیت های زیادی دیسک می شود که در آن صفحات از حافظه به دیسک و از دیسک به حافظه آورده می شوند پردازش بسیار کمی اتفاق می افتد اگر سیستم به خوبی کار کند ما یک سیستم حافظه مجازی خواهیم داد. موقعیت زیر را تصور کنید:
یک کامپیوتر دارای 10 مگابیت حافظه می باشد که به صفحات 10 * 1 مگابیت صفحه بندی شده است هر صفحه دارای یک ادرس فیزیکی (واقعی) و صفحه آدرس می باشد. یک برنامه 20 مگابیت فضا می گیرد و مجددا صفحه بندی می شود. وقتی برنامه شروع می شود 10 مگابیت اول در برنامه بارگذاری می شود. پردازش شروع شده و تا زمانی که به یک آدرس در خارج از ده مگابیت نیاز است ادامه پیدا می کند. در این نقطه سیستم عامل یک اختلال ایجاد می کند که پردازش شده و به آن پاسخ داده می شود در این حالت سیستم یک صفحه حافظه را با یک صفحه ذخیره شده در دیسک جایگزین می کند. در اصل حافظه برای کاربر این گونه به نظر می رسد که حافظه واقعی (RAM) به اضافه ظرفیت درایو هارد می باشد.
تکنیک های پیچیده مدیریت حافظه باید برای متوقف کردن یک برنامه از همپوشانی حوزه حافظه دیگری مورد استفاده قرار گیرند.
به هر برنامه باید حوزه حافظه مخصوص به خود داده شود و تحت شرایط طبیعی هیچ برنامه دیگری به ان دسترسی نخواهد داشت. درموقعیتی که در آن دو برنامه حافظه را به طور همزمان اشغال می کند اگر برنامه A داده ها در حوزه برنامه B را تغییردهد آن گاه برنامه B احتمالاً متوقف خواهد شد. در نسخه های اولیه ویندوز این کار سیستم عامل را نیز متوقف می کرد. شرایطی وجود دارد که در ان این قانون شکسته شده است. در برنامه های ویندوز این امکان وجود دارد که تا از یک برنامه به برنامه دیگر کات و پیست کرد. داده ها در یک حوزه همپوشانی کات شده و سپس از این حوزه پیست می شود