موضوع مقاله: سمافور | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # سمافور | مقدمه: سمافور می‌تواند به دو صورت دودویی (که تنها دو مقدار صحیح و غلط را دارا است) یا شمارنده اعداد صحیح باشد. | ## بخش 1: سمافور | به این ترتیب، اطمینان حاصل می‌شود که در هر لحظه تنها یک فرایند به منبع مشترک دسترسی دارد و می‌تواند از آن بخواند یا بنویسد (انحصار متقابل) سمافورها اولین بار به‌وسیلهٔ دانشمند علوم رایانه هلندی، ادسخر دیکسترا معرفی شدند. برای جلوگیری از مجادله و نزاع، دانشجویانی که قصد مطالعه دارند‍، باید اتاقی را از یک پیشخوان درخواست دهند. وقتی که یک دانشجو مطالعه‌اش تمام شد و خواست اتاق را تحویل دهد، باید مجدداً به پیشخوان برگردد و نشان دهد که دیگر به اتاق احتیاج ندارد. اگر هیچ اتاق خالی وجود نداشت و همه اتاق‌ها از قبل اشغال شده بود، دانشجویان باید منتظر بمانند تا یکی از دانشجو ها اتاقش را تحویل دهد. سپس دانشجویی که بالاترین اولویت را نسبت به بقیه دارد (مثلاً زودتر از بقیه آمده) می‌تواند اتاق خالی شده را انتخاب کند. منشی که در پیشخوان حاضر است، پیگیری نمی‌کند که کدام اتاق اشغال شده‌است یا چه کسی از آن اتاق استفاده می‌کند، او تنها تعداد اتاق‌های خالی را می‌داند. وقتی که دانشجویی اتاقی را تقاضا می‌کند، منشی تعداد اتاق ‌های خالی را یک واحد کم می‌کند. وقتی که دانشجویی اتاقی که قبلاً گرفته بود را پس می‌دهد، منشی این عدد را یک واحد افزایش می‌دهد. وقتی که دانشجویی توانست اتاقی را بردارد، می‌تواند تا هر وقت که خواست همان‌جا بماند و از آن استفاده کند، بنابراین رزرو کردن اتاق‌ها از قبل امکان‌پذیر نیست. وقتی که اولین دانشجو اتاقی را درخواست می‌کند، منشی اتاق را به او اختصاص داده و مقدار سمافور را به ۹ کاهش می‌دهد. وقتی که دانشجوی بعدی وارد شد، این عدد به ۸ و سپس به ۷ و به همین ترتیب کاهش می‌یابد. اگر دانشجویی اتاقی را درخواست دهد، اما مقدار سمافور منفی باشد، مجبور است منتظر بماند تا یکی از دانشجوها اتاقش را پس دهد. اگر سمافوری به نام S داشته باشیم، عملیات V آن را یک واحد افزایش می‌دهد و عملیات P یک واحد آن را کاهش می‌دهد. | ## بخش 2: سمافور | عملیات اتمی به عملیاتی می‌گویند که تجزیه ناپذیر باشد، یا کل آن اجرا می‌شود یا اصلاً اجرا نمی‌شود. وقتی که پروسه‌ای کارش را با منبع به اتمام رساند، با استفاده از عملیات V می‌تواند آن را آزادسازی کند تا دیگر پروسه‌ها بتوانند از آن استفاده کنند. خصوصیت مهم سمافور S این است که مقدار آن را تنها می‌توان به وسیله عمیات‌های V و P تغییر داد. پس از افزایش دادن، اگر مقدار قبل سمافور منفی باشد (به این معنی که در حال حاضر پروسه‌هایی در صف سمافور منتظر دریافت منبع هستند)، یکی از پروسه‌ها از صف آماده وارد صف اجرا می‌شود و منبع آزاد شده را در اختیار می‌گیرد. هر فرایند را می‌توان در نقطهٔ خاصی از اجرا متوقف نموده، و تا رسیدن سیگنال خاصی از اجرای آن جلوگیری نمود. هر فرایندی که بخواهد به منبع مشترک دسترسی داشته باشد، اعمال زیر را انجام خواهد داد: مقدار سمافور را بررسی می‌کند. در این صورت، فرایند یک واحد از سمافور می‌کاهد تا نشان دهد که یک واحد از منبع مشترک را استفاده نموده‌است. در صورتی که مقدار سمافور صفر یا کوچکتر از صفر باشد، فرایند به خواب می‌رود تا زمانی که سمافور مقداری مثبت به خود بگیرد. هر زمان که مقدار سمافور به صفر یا بیشتر برسد، یکی از فرایند(هایی) که به خواب رفته به صورت تصادفی یا به روش FIFO توسط سیستم‌عامل بیدار می‌شود. در این حالت بلافاصله فرایند بیدار شده منبع را در دست می‌گیرد و مجدداً پس از اتمام کار یک واحد از سمافور کم می‌شود. اگر مقدار سمافوری صفر باشد و چند فرایند بلوکه شده در آن وجود داشته باشد، با افزایش یک واحدی سمافور، مقدار سمافور همچنان صفر باقی می‌ماند اما یکی از فرایندهای بلوکه شده آزاد می‌شود. سمافور باید مستقل از فرایندها بوده و در فضایی از حافظه قرار گیرد که فرایندها بتوانند به آن دسترسی داشته باشند، همچنین عملیاتی که روی سمافور انجام می‌گیرد باید به صورتی پیاده‌سازی گردد که هیچ گونه وقفهای هنگام انجام آن عملیات به وجود نیاید (اتمیک باشد). به همین دلیل، سمافور در هسته سیستم‌عامل پیاده‌سازی می‌گردد و کنترل آن نیز توسط سیستم عامل صورت می‌گیرد. | ## بخش 3: سمافور | سمافورها معمولاً به‌طور مستقیم مورد استفاده قرار نمی‌گیرند، مگر در جایی که راه حل سطح بالایی وجود نداشته باشد. چرا که برنامه‌نویس می‌تواند با ایجاد شرایطی، به بن‌بست رسیده یا فرایندهایی را گرسنه نگاه دارد (اجازهٔ دسترسی به منبع را برای مدتی طولانی ندهد.) پیاده‌سازی‌ها پازیکس استاندارد پازیکس دسته‌ای تابع برای کار بر روی سمافورها تعریف می‌کند که در سیستم‌عاملهای سازگار با این استاندارد قابل استفاده هستند. اگر پارامتر pshared غیر صفر باشد، مشخص‌کننده سمافور مشترکی است که می‌تواند توسط چند فرایند مورد استفاده قرار بگیرد. به عبارت دیگر، پارامتر pshared تعیین می‌کند که آیا سمافور قرار است بین ریسه‌های یک فرایند به اشتراک گذاشته شود یا بین چند فرایند مجزا. برای اشتراک گذاشتن یک سمافور بین چند فرایند، سمافور باید در یک حافظه مشترک قرار گیرد تا همه فرایندها بتوانند به آن دسترسی داشته باشند. هر پروسه‌ای که به آدرس sem دسترسی داشته باشد، می‌تواند بر روی سمافور عملیات انجام دهد. بعد از اینکه این تابع بر روی یک سمافور با موفقیت اجرا شد، می‌تواند از آن سمافور در توابع دیگر استفاده کرد. این تابع در صورت موفقیت مقدار صفر و در صورت شکست مقدار -1 را برمی‌گرداند و متغیر سراسری errno را با خطای مورد نظر مقداردهی می‌کند. اگر مقدار فعلی سمافور صفر باشد (به این معنی که هم‌اکنون منبع اشتراکی در اختیار فرایند دیگری است)، فرایند فراخوان بلوکه می‌شود، تا وقتی که فرایند دیگر منبع اشتراکی را آزاد کند. اما اگر مقدار سمافور صفر باشد، پروسه بلوکه نخواهد شد و در عوض یک خطا برخواهد گشت. پس از اینکه فرایندها کار خود را با منبع اشتراکی به اتمام رساندند، باید این تابع را بر روی سمافور فراخوانی کنند تا فرایندهای دیگر بتوانند از منبع استفاده کنند. اگر در حال حاضر فرایند(هایی) بر روی سمافور بلوکه شده باشد، فرایندی که اولویت بالاتری دارد بیدار شده و منبع را در دست خواهد گرفت. | ## جمع‌بندی | پس از اینکه این تابع بر روی یک سمافور با موفقیت اجرا شد، سمافور مورد نظر دیگر قابل استفاده نیست و هیچ تابعی نباید بر روی آن منتظر دستیابی به منبع اشتراکی باشد.