سیستم عامل یونیکس(Unix OS)-بخش سوم
راهکارهای همزمانی در یونیکس
یونیکس راهکارهای متنوعی را برای ارتباط و همگام سازی فرایندها فراهم کرده است. در اینجا مهمترین آنها را مورد توجه قرار می دهیم:
- لوله ها
- پیامها
- حافظه مشترک
- راهنماها
- علائم
لوله های پیام ها و حافظه مشترک وسایلی برای مخابره داده ها در بین فرایندها فراهم میکنند در حالی که از راهنماها و علائم برای راه اندازی اعمال به وسیله فرایندهای دیگر استفاده میشود.
لوله ها
یکی از مهمترین کمک های یونیکس به ایجاد و توسعه سیستم های عامل، لوله است. با الهام از مفهوم هم روال لوله میانگیر مدوری است که اجازه میدهد دو فرایند بر اساس مدل تولید کننده و مصرف کننده ارتباط برقرار کنند. بنابراین صف خروج به ترتیب ورودی است که به وسیله یک فرایند نوشته و توسط دیگری خوانده میشود.
در هنگام ایجاد لوله اندازه ثابتی از بایتها برایش منظور میشود. وقتی فرایندی برای نوشتن در لوله ها تلاش کند، در صورت وجود جا درخواست نوشتن بلافاصله اجرا میشود. درغیر این صورت آن فرایند مسدود میگردد. همین طور اگر فرایندی برای خواندن بیش از بایتهایی که در لوله موجود هست تلاش کند مسدود میشود وگرنه درخواست خواندن، بلافاصله اجرا میگردد. سیستم عامل انحصار متقابل را اعمال مینماید. یعنی در هر زمان تنها یک فرایند می تواند به لوله دسترسی داشته باشد.
دو نوع لوله، با نام و بی نام وجود دارد. لوله های بی نام را تنها فرایندهای مرتبط میتوانند مشترک شوند درحالی که فرایندهایی که مربوط بهم نیستند تنها میتوانند لوله های با نام را مشترک گردند.
پیام ها
پیام ،بلوکی از متن به همراه یک نوع است. یونیکس از فراخوانی های سیستم msgsnd و msgrev برای فرایندهای درگیر در تبادل پیام استفاده میکند. هر فرایند یک پیام وابسته است که مثل یک صندوق پستی عمل میکند.
فرستنده پیام با هر پیام ارسالی نوع آن را نیز مشخص میکند. این نوع میتواند به عنوان معیار انتخاب توسط دریافت کننده به کار رود. دریافت کننده میتواند پیامها را بر مبنای خروج به ترتیب ورود و یا بر مبنای نوع آنها دریافت نماید. اگر فرایندی برای ارسال پیام به صفی که پر است تلاش کند، معلق خواهد شد. اگر فرایندی برای خواندن از صف خالی تلاش کند نیز معلق میگردد. اگر فرایندی برای خواندن نوع خاصی از پیام تلاش کند و موفق نشود، این فرایند معلق نخواهد شد.
حافظه مشترک
سریعترین شکل ارتباط بین فرایندها که در یونیکس فراهم شده حافظه مشترک است.بلوکی از حافظه مجازی است که توسط فرایندهای متعدد مورد اشتراک قرار میگردد. فرایندها میتوانند با استفاده از همان دستورالعمل های ماشین که برای خواندن و نوشتن بخش های دیگر حافظه مجازی به کار میبرند،حافظه مشترک را نیز بخوانند یا بنویسند. مجوز هر فرایند فقط خواندن یا خواندن و نوشتن است که برای هر فرایند به طور جداگانه تعیین میگردد. محدودیت های انحصار متقابل بخشی از امکان حافظه مشترک نیست ولی باید توسط فرایندهایی که از حافظه مشترک استفاده میکنند فراهم گردد.
راهنماها
فراخوانی های سیستمی راهنما در unix xyxtem V تعمیمی از اولیه هایwait , signal معرفی شده است.به این صورت که عملیات متعددی میتوانند به صورت همزمان انجام شوند و اعمال افزایش و کاهش با مقادیر بزرگتر از یک نیز میتواند انجام گردد. هسته تمام اعمال در خواست شده را به صورت اتمی انجام میدهد . یعنی تا موقعی که تمام اعمال انجام نشده باشد، هیچ فرایند دیگری نمیتواند به آن راهنما دسترسی داشته باشد.
یک راهنما شامل عناصر زیر است:
- مقدار جاری راهنما
- شناسه یا ID آخرین فرایند عملکننده روی این راهنما
- تعداد فرایندهایی که منتظرند تا مقدار این راهنما از مقدار جاری آن بیشتر شود
- تعداد فرایندهایی که منتظرند تا مقدار این راهنما صفر شود.
صف های فرایندهایی که روی این راهنما معلق هستند نیز به آن راهنما وابسته اند.
در واقع راهنماها به صورت مجموعه هایی ایجاد میشوند، که هر مجموعه راهنما شامل یک راهنما یا بیشتر است. فراخوانی سیستم semctl اجازه میدهد تا تمام راهنماهای یک مجموعه راهنما در یک زمان مقدار گذاری شوند. علاوه بر این فراخوانی سیستمی semop وجود دارد که لیستی از اعمال راهنماها (که هر یک روی راهنما یی از مجموعه تعریف شده است) را به عنوان نشانوند دریافت کند.با این فراخوانی هسته اعمال مشخص شده را یکی یکی انجام می دهد. برای هر عمل کار واقعی به وسیله مقدار sem-opمشخص شده است. موارد ممکن در زیر آمده است:
- اگر sem-op مثبت باشد هسته مقدار راهنما را افزایش داده و تمام فرایندهایی که منتظر افزایش مقدار راهنما بودند را بیدار میکند.
- اگر sem-op صفر باشد هسته مقدار راهنما را بررسی میکند. اگر صفر باشد با اعمال دیگر لیست ادامه میدهد. در غیر این صورت تعداد فرایندهایی که منتظر صفر بودن این راهنما هستند را افزایش داده و آن فرایند را روی حادثه صفر شدن مقدار این راهنما معلق میکند.
- اگر sem-op منفی و قدر مطلقش کمتر یا مساوی مقدار راهنما باشد هسته sem-op یک عدد منفی را به مقدار راهنما میافزاید. اگر نتیجه صفر باشد هسته تمام فرایندهایی که منتظر صفر بودن مقدار راهنما بوده اند را بیدار میکند.
- اگر sem-op منفی و قدر مطلقش بزرگتر از مقدار راهنما باشد هسته این فرایند را برای حادثه افزایش مقدار راهنما معلق میکند.
این تعمیم از راهنما،انعطاف قابل ملاحظه ای در انجام همگام سازی و هماهنگی فرایند ها فراهم میکند.
در واقع Semaphore یک واژه و اصطلاح در یونیکس برای متغیری است که شبیه شمارشگر عمل میکند.
دلیل این که چرا باید از این استفاده شود بسیار ساده است.
زمان هایی پیش میآید که چند Process به صورت همزمان میخواهد به یک پوشه مشخص دسترسی داشته باشند، در این حالت باید بتوانیم دسترسی به پوشه را زمانیکه یک Process دسترسی به آن دارد، کنترل نماییم. این کار با مقدار دهی Semaphore انجام میشود.
Semaphore توسط Process اول مقدار دهی اولیه میشود.
وقتی که Process دوم میخواهد به پوشه دسترسی داشته باشد، semaphore را چک مینماید و اگر مقدار آن برابر مقدار اولیه باشد در این صورت به پوشه دسترسی نخواهد داشت.
پس از اینکه کار Process اول تمام شد، مقدار Semaphore مجدد مقدار دهی مینماید، و بدین ترتیب Process دوم میتواند به پوشه دسترسی داشته باشد.
دوپارامتر عملکرد الگوریتم را مشخص می نمایند:
Scanrate :
سرعتی که هر کدام از Hand ها لیستPage ها(صفحات) را اسکن می کنند،با واحد Page(صفحه) بر ثانیه.
Handspread:
فاصله بین Fronthand و Backhand.
این پارامترها مقدار اولیه دارند که در هنگام بوت شدن و براساس حجم حافظه مشخص می شوند.
سرعت
سرعت یک سیستم هم به مشخصات سخت افزار بستگی دارد و هم به سیستم عامل.
میزان فضای حافظه، نوع پردازنده (RISC یا CISC بودن معماری پردازنده)، سرعت کار پردازنده و سایر قطعات (از جمله برد اصلی، دیسک، کارت شبکه، …) از جمله فاکتورهای سخت افزاری تعیین کننده سرعت می باشند. نحوه عملکرد سیستم عامل نقش مهمی در سرعت سیستم دارد. سرعت سیستمهای UNIX به مراتب بهتر از سیستمهای Windows می باشند. Windows مشکلات زیادی در مدیریت حافظه دارد ولی UNIX از حافظه استفاده بهینه می کند و فضای حافظه را هدر نمی دهد، بطوریکه حتی قسمتهایی از خود سیستم عامل نیز به صورت module می باشند که فقط در صورت نیاز در حافظه قرار می گیرند.
علائم
علامت یک راهکار نرم افزاری است که یک فرایند را از بروز حوادث ناهنگام با خبر میکند. علامت شبیه یک وقفه سخت افزای است که اولویت ها را به کار نمی برد. یعنی همه علائم به طور معادل عمل میکنند. علائمی که در این زمان اتفاق بیفتند یکی یکی و بدون هیچ ترتیب خاصی به یک فرایند ارائه میگردند.
ممکن است فرایندها برای یکدیگر علامت بفرستند یا ممکن است هسته به صورت داخلی علائم را بفرستد. تحویل یک علامت با بهنگام کردن عنصری از جدول فرایند تحویل گیرند، انجام میشود. نظر به اینکه هر علامت به صورت یک بیت واحد نگهداری میشود. علائم از یک نوع خاص به صف نمیشوند. پردازش علامت دقیقا بعد از بیدار شدن فرایند برای اجرا یا برگشت از یک فراخوانی سیستم صورت میگیرد. پاسخگویی فرایند به یک علامت ممکن است توسط بعضی اعمال پیش فرض اجرای یک تابع گرداننده علامت و یا با نادیده گرفتن علامت انجام شود.
اولیه های همگام سازی نخ در SOLARIS
علاوه بر راهکارهای همزمان UNIX SVR4 سیستم عامل SOLARISازچهار اولیه همگام سازی نخ حمایت میکند:
- قفل های انحصار متقابل
- راهنماها
- قفل های چند خواننده و یک نویسنده
- متغیرهای شرط
SOARSI این اولیه ها را در داخل هسته برای نخهای هسته پیاده سازی میکند. برای استفاده نخ های سطح کاربر این اولیه ها در کتابخانه نخ ها هم فراهم شده است. اجرای یک اولیه موجب ایجاد ساختمان داده هایی میشود که حاوی پارامترهای مشخص شده توسط نخ ایجاد کننده است.
وقتی یک شی همگام سازی ایجاد شد اساسا فقط دو عمل میتوان انجام داد: وارد شدن و رها کردن. برای اعمال انحصار متقابل یا پیشگیری از بن بست هیچ راهکاری در هسته یا کتابخانه نخها وجود ندارد. اگر نخی برای دسترسی به داده ها یا کدی که قرار بوده حفاظت شود تلاش کند،ولی از اولیه های همگام سازی استفاده نکند، در این صورت چنین دسترسی اتفاق می افتد. اگر نخی شی را قفل کند ولی موفق به بازکردن آن نشود هیچ عمل هسته ای انجام نمی شود.
تمام اولیه های همگام سازی به دستور العمل سخت افزاری نیاز دارند که ازمون و مقدار گذاری در یک شی را به صورت تجزیه نشدنی انجام دهد.
قفل انحصار متقابل
با اجرای اولیه MUTEX –ENTER یک نخ میتواند برای به دست آوردن قفل MUTEX تلاش کند. اگر نخی قفل MUTEX را به دست آورد. این قفل از پیشرفت بیش از یک نخ جلوگیری می کند. نخی که MUTEX را قفل می کند باید خودش آن را باز نماید. اگر MUTEX-ENTER نتواند قفل کند، عمل مسدود شدن به اطلاعات ویژه نوع که در شی MUTEX ذخیره شده است، بستگی دارد. سیاست پیش فرض مسدود کردن یک قفل چرخشی است،یعنی نخ مسدود در حالی که یک حلقه انتظار را اجرا می کند، وضعیت قفل را مورد سئوال قرار می دهد. راهکار مسدود کردن مبتنی بر وقفه اختیاری است. در حالت اخیر MUTEX شامل شناسه ای است که صف نخ های در حال خواب برای این قفل را مشخص میکند.
اولیه های مربوط به قفل MUTEX عبارتند از:
- قفل را بدست می آورد و اگر قفل گرفته شده باشد،بالقوه مسدود کننده است. ()MUTEX-ENTER
- قفل را رها می کند و بالقوه یک منتظر را از مسدود بودن در می آورد ()MUTEX-EXIT
- اگر قفل گرفته نشده باشد ،آن را به دست می آورد. ()MUTEX-TRYENTER
اولیه ()MUTEX-TRYENTER یک راه مسدود نشدنی برای انجام عمل انحصار متقابل را ارائه میکند. به این ترتیب برنامه سازی میتواند با استفاده از یک رویکرد انتظار مشغولی برای نخ های سطح کاربر، از مسدود شدن کل فرایند به دلیل مسدود بدون یک نخ، دوری کند.
راهنماها
با اولیه های زیر SOLARIS راهنماهای شمارنده کلاسیک را ارائه می کند:
- راهنما را کاهش می دهد و بالقوه، مسدود کننده نخ است. ()SEMA-P
- راهنما را افزایش می دهد و بالقوه، یک نخ را از مسدود بودن خارج می کند ()SEMA-V
- اگر مسدود شدن لازم نباشد، از راهنما کم می کند. ()SEMA-TRYP
اولیه ()SEMS-TRYP انتظار مشعولی را هم ارائه می کند.