به محیط اجرایی فرآیندهای عادی (بر خلاف کرنل) “فضای کاربر” گفته میشود. الزماً به این معنی نیست که این فرآیندها در حقیقت توسط کاربر اجرا میشوند چرا که یک سیستم استاندارد شامل چند “daemon” (پسزمینه) است که قبل از ورود کاربر به سیستم، فرآیندها را اجرا میکنند. این فرآیندها همچنین به عنوان فرآیندهای فضای-کاربر شناخته میشوند.
زمانی که کرنل فاز اولیه خود را میگذراند، اولین فرآیند موجود را آغاز میکند، init
. فرآیند شماره ۱ به خودی خود کاربردی ندارد، به همین دلیل است که سیستمهای شبه-یونیکس فرآیندهای بسیار دیگری را اجرا میکنند.
اول از همه، یک فرآیند میتواند خودش را شبیهسازی کند (که البته با نام fork شناخته میشود). کرنل در این حالت یک فضای حافظه جدید (اما برابر) همچنین فرآیند دیگری که از آن استفاده کند، اختصاص میدهد. در این زمان، تنها تفاوت موجود بین این دو فرآیند pid آنها است. فرآیند جدید معمولاً بنام فرزند و فرآیند اصلی که pid آن تغییر نکرده است بنام پدر نامگذاری میشوند.
گاهی اوقات، فرآیند فرزند به حیات خود مستقل از فرآیند پدر ادامه میدهد، با دادههای خودش که از فرآیند پدر کپی شده است. در بسیاری موارد، البته، این فرآیند فرزند برنامه دیگری را اجرا میکند. بجز موارد خاص، حافظه آن به سادگی با آن برنامه جدید جایگزین میشود و اجرای این برنامه جدید آغاز میگردد. این مکانیزمی است که فرآیند init (با شماره فرآیند ۱) از آن استفاده میکند تا سرویسهای اضافی را راهاندازی کرده و به اجرای تمام مراحل بارگذاری سیستم بپردازد. در برخی نقاط، یک فرآیند از میان فرزندان
init
مبادرت به اجرای یک رابط گرافیکی میکند تا کاربران بتوانند وارد آن شوند (ترتیب دقیق این رویدادها به طور مشروح در
قسمت 9.1, “راهاندازی سیستم”
آمده است).
زمانی که یک فرآیند به اتمام کار خود میرسد، نابود میگردد. کرنل در این زمان حافظهای که به آن تخصیص داده بود را بازیابی میکند و دیگر بازههای زمانی در اختیارش قرار نمیدهد. همچنین به فرآیند پدر نیز اطلاع داده میشود که فرزندش نابود شده است، که این امکان را به یک فرآیندی که تحت فرآیند فرزند اجرا شده است میدهد تا عملیات مربوط به خود را قبل از نابودشدن آن انجام دهد. این رفتار به وضوح در مفسرهای خط فرمان (که با نام shell شناخته میشوند) قابل رویت است. زمانی که یک دستور درون خط فرمان نوشته میشود، کنترل خط فرمان تنها زمانی به کاربر بر میگردد که آن دستور تمام شده باشد. اکثر خطفرمانها اجازه اجرای دستور در پسزمینه را میدهند، که این عمل به سادگی با اضافه کردن یک &
به انتهای دستور ممکن است. در این حالت، خط فرمان بلافاصله در اختیار کاربر قرار میگیرد، البته ممکن است در شرایطی که دستور نیاز به نمایش برخی دادهها داشته باشد مشکل آفرین گردد.
B.5.2. فرآیندهای پسزمینه
یک “daemon” فرآیندی است که به صورت خودکار در زمان راهاندازی سیستم اجرا میشود. این فرآیند به اجرای خود (در پسزمینه) ادامه میدهد تا برخی وظایف نگهداری را انجام داده یا برخی سرویسها را در اختیار سایر فرآیندها بگذارد. این “وظیفه پسزمینه” در حقیقت نامی دلخواه است که از دید کلی سیستم معنای خاصی نمیدهد. آنها به سادگی، همان فرآیندها هستند، درست مانند سایر فرآیندها که هر زمان نوبتشان فرا برسد اجرا میشوند. تفاوت تنها در نامگذاری است که ما برایشان انتخاب کردیم: فرآیندی که بدون تعامل کاربر اجرا میشود (به طور خاص، بدون هیچ رابط گرافیکی) به عنوان فرآیند “پسزمینه” یا “daemon” شناخته میشود.
B.5.3. ارتباطات بین-فرآیندی
یک فرآیند جدا شده (ایزوله)، خواه پسزمینه باشد یا یک برنامه کاربردی، به خودی خود کاربردی ندارد، به همین دلیل است که روشهای گوناگونی برای ارتباط و تعامل بین این فرآیندها وجود دارد، خواه برای تبادل داده یا کنترل یکدیگر. عبارت عمومی که به این منظور استفاده میشود ارتباط بین-فرآیندی یا به طور خلاصه IPC نام دارد.
سادهترین سیستم IPC از فایلها استفاده میکند. فرآیندی که طی آن فرستنده، داده را جهت ذخیرهسازی روی یک فایل (با نامی که در ادامهاش میآید) ارسال میکند و گیرنده تنها باید فایل را باز کرده و محتویات آن را بخواند.
در صورتی که نخواهید داده را روی دیسک ذخیره کنید، میتوانید از یک لوله استفاده کنید، که در سادهترین حالت یک مدخل دوطرفه است؛ بایتهایی که در یک طرف نوشته میشوند در طرف دیگر قابل خواندن هستند. اگر طرفین این لوله توسط فرآیندهای جداگانهای کنترل میشوند، این عملیات به یک کانال ارتباط بین-فرآیندی ساده تبدیل میشود. لولهها میتوانند به دو طبقهبندی تقسیم شوند: لولههای نامدار و لولههای بینام و نشان. یک لوله نامدار توسط یک مدخل در فایلسیستم نمایش داده میشود (با اینکه داده تبادل یافته آنجا ذخیره نمیشود)، بنابراین هر دو فرآیند میتوانند آن را جداگانه باز کنند در صورتی که مکان لوله نامدار قبل از آن ذکر شده باشد. در مواردی که فرآیندهای در حال تعامل به یکدیگر مربوط هستند (برای نمونه، یک فرآیند پدر و فرزند)، فرآیند پدر میتواند قبل از عملیات شبیهسازی یک لوله بینام و نشان ایجاد کند تا فرزندش آن را به ارث ببرد. هر دو فرآیند در این حالت قادر به تبادل داده هستند بدون آنکه به فایلسیستم نیازی داشته باشند.
البته، تمام ارتباطات بین-فرآیندی جهت تبادل داده بکار نمیروند. در شرایط دیگر، تنها اطلاعاتی که نیاز به رد و بدل شدند دارند پیامهای کنترلی مانند “توقف اجرا” یا “ادامه اجرا” میباشند. یونیکس (و لینوکس) مکانیزمی با نام سیگنال فراهم میآورد، که از طریق آن یک فرآیند میتواند یک سیگنال مشخص (که از فهرست از پیش آماده شده سیگنالها انتخاب شده است) را به فرآیند دیگر ارسال کند. تنها پیشنیاز این ارتباط، دانستن pid فرآیند هدف است.
برای ارتباطات پیچیدهتر، مکانیزمهایی وجود دارند که یه یک فرآیند اجازه دسترسی یا اشتراکگذاری برخی از حافظه تخصیص یافته خود را به سایر فرآیندها میدهد. اکنون از حافظه اشتراکی بین این دو فرآیند میتوان به عنوان کانالی جهت تبادل داده استفاده کرد.
در نهایت، ارتباطات شبکه نیز میتواند به ارتباط فرآیندها کمک کند؛ این فرآیندها حتی در رایانههای مختلف اجرا میشوند، که احتمالاً هزاران کیلومتر از یکدیگر فاصله دارند.
تقریباً برای یک سیستم شبه-یونیکس بسیار متداول است که بسیاری از این مکانیزمها را در درجات مختلف بکار گیرد.
کتابخانههای تابعی نقشی حیاتی در سیستمهای شبه-یونیکس ایفا میکنند. آنها برنامههای آماده نیستند، چرا که به خودی خود قابلیت اجرا شدن ندارند، اما مجموعههایی جدا جدا از کد هستند که قابلیت استفاده توسط برنامههای استاندارد را دارند. در میان این کتابخانههای عمومی، میتوانید مواردی زیر را پیدا کنید:
کتابخانه استاندارد C (glibc)، که شامل توابع پایه مانند بازکردن فایل یا ارتباط شبکه و سایر ابزارهای تعاملی با کرنل است؛
ابزارهای گرافیکی، مانند +GTK و Qt به بسیاری از برنامهها این امکان را میدهند تا از قسمتهای مختلف یک محیط گرافیکی استفاده کنند؛
کتابخانه libpng، که امکان بارگذاری، تفسیر و ذخیره تصاویر در قالب PNG را فراهم میکند.
به لطف این کتابخانهها، برنامههای کاربردی میتوانند از کد موجود استفاده کنند. توسعه برنامهها آسانتر شده است چرا از بسیاری توابع موجود استفاده میکنند. با کتابخانههایی که توسط افراد گوناگون توسعه یافته است، توسعه سراسری سیستم به فلسفه تاریخی یونیکس نزدیکتر شده است.
بر این به، أنها اغلب کتابخانههای “اشتراکی گفته” میشود چرا، که کرنل تنها قادر است علاوه آنها را یکبار در حافظه بارگذاری نماید با اینکه فرآیندهای بسیاری میتوانند به طور همزمان از آنها استفاده کنند. اینکار امکان صرفهجویی در حافظه را فراهم میآورد در مقایسه با شرایط عکس آن (به صورت فرضی) که کد موجود در کتابخانه به تعداد دفعاتی که فرآیندها از آن استفاده میکنند در حافظه قرار داده شود.