يشير ”فضاء المستخدم user space“ إلى بيئة تشغيل العمليات العادية (مقارنة بعمليات النواة). لا يعني هذا بالضرورة أن المستخدم يُشَغِّل هذه العمليات لأن النظام القياسي يحوي في الحالة الطبيعية عدة عمليات خدمية (تعمل في الخلفية) تعمل قبل أن يفتح المستخدم أي جلسة عمل أصلاً. تعتبر العمليات الخدمية تابعة لفضاء المستخدم أيضاً.
عندما تنهي النواة طور تهيئتها، تبدأ العملية الأولى، init
. العملية #1 وحدها نادراً ما تكون مفيدة بحد ذاتها، ونظم التشغيل المشابهة لنظام يونكس تحوي عمليات إضافية عديدة.
أولاً، يمكن للعملية استنساخ نفسها (تعرف هذه العملية بالاشتقاق fork). تخصص النواة مساحة ذاكرة جديدة للعملية (لكن مطابقة للقديمة)، وعملية أخرى لاستخدامها. عند هذه اللحظة، الاختلاف الوحيد بين العمليتين هو رقم التعريف pid. تدعى العملية الجديدة بالعملية الابن عادة، والعملية الأصل التي لم يتغير رقم تعريفها، بالعملية الأم.
أحياناً تتابع العملية الابن قيادة حياتها الخاصة مستقلة عن الأم، باستخدام بياناتها الخاصة المنسوخة عن العملية الأم.لكن في حالات عديدة تنفذ هذه العملية الابن برنامجاً آخر، حيث تُستَبدل ذاكرتها ببساطة بذاكرة البرنامج الجديد، ويبدأ تنفيذ هذا البرنامج إلا في بعض الاستثناءات القليلة. هذه هي الآلية التي تعتمدها عملية init (العملية رقم 1) لبدء الخدمات الإضافية وتنفيذ سلسلة الإقلاع كلها. وفي لحظة ما، تبدأ إحدى العمليات من ذرية
init
واجهة رسومية حتى يسجل المستخدمون دخولهم (التسلسل الحقيقي للأحداث مشروح بمزيد من التفصيل في
قسم 9.1, “إقلاع النظام”).
عندما تنهي العملية المهمة التي بدأت لأجلها، تنتهي العملية. بعدها تستعيد النواة الذاكرة المخصصة لهذه العملية، وتقطع عنها شرائح التشغيل الزمنية. يتم إعلام العملية الأم عن انتهاء عمليتها الابن، ما يسمح لعملية ما أن تنتظر إنهاء مهمة فوضت أحد أبنائها بها. هذا السلوك واضح للعين المجردة في مفسرات سطر الأوامر (تعرف باسم الأصداف shells). عند كتابة أمر في الصَدَفَة، لا تعود إشارة الإدخال قبل انتهاء تنفيذ الأمر. تسمح معظم الأصداف بتشغيل الأوامر في الخلفية، يكون ذلك بسهولة بإضافة &
إلى نهاية الأمر. بعدها تظهر إشارة الإدخال مجددًا مباشرة، وهذا قد يسبب مشاكل إذا كان الأمر يحتاج لإظهار بيانات خاصة به.
”الجني daemon“ هو عملية تُشغِّلها متتالية الإقلاع آلياً. يبقى نشطاً (في الخلفية) لتنفيذ مهام صيانة أو تقديم خدمات للعمليات الأخرى. هذه ”المهمة في الخلفية“ عشوائية في الحقيقة، ولا تقابل أي شيء محدد من وجهة نظر النظام. هي مجرد عمليات، شبيهة بالعمليات الأخرى تماماً، التي تعمل بدورها عندما تحين حصتها من الوقت. هذا التمييز موجود في لغة البشر فقط: أية عملية تعمل بدون أي تفاعل مع المستخدم (على الأخص، بدون واجهة رسومية) يقال أنها تعمل ”في الخلفية“ أو أنها ”جني“.
B.5.3. التواصل بين العمليات
إن العملية المعزولة، سواء كانت خدمة أو تطبيقًا تفاعليًا، نادراً ما تكون مفيدة بحد ذاتها، وهو السبب وراء وجود العديد من أساليب التواصل بين العمليات المنفصلة، سواء لتبادل البيانات أو لتتحكم واحدتها بالأخرى. المصطلح العام للتعبير عن هذا المفهوم هو التواصل بين العمليات inter-process communication، أو IPC اختصاراً.
أبسط نظام IPC هو استخدام الملفات. تكتب العملية التي ترغب بإرسال البيانات بياناتها في ملف (له اسم معروف مسبقًا)، في حين تحتاج العملية المتلقية إلى فتح الملف وقراءة محتوياته فقط.
في الحالات التي لا ترغب فيها بتخزين البيانات على القرص، يمكنك استخدام أنبوب، وهو ببساطة عنصر له نهايتان؛ البايتات المكتوبة في إحداهما، تكون مقروءة عند النهاية الأخرى. إذا تَحكَّمَت بالنهايتين عمليتين منفصلتين، يصبح الأنبوب بمثابة قناة تواصل بين العمليات بسيطة وسهلة الاستعمال. يمكن تصنيف الأنابيب في زمرتين: الأنابيب المسمّاة، والأنابيب المجهولة. يُمثَّل الأنبوب المسمى بمدخلة في نظام الملفات (مع أن البيانات المرسلة لا تُخزَّن هناك)، بحيث يمكن لكلا العمليتين فتحه بشكل مستقل إذا كان موقع الأنبوب المسمى معروفًا من قبل. في الحالات التي تكون فيها العمليات التي تتواصل فيما بينها مرتبطة ببعضها (مثلاً، عملية أم مع ابنها)، يمكن للعملية الأم أيضًا إنشاء أنبوب مجهول قبل الاشتقاق، وسيرثه الابن. ستتمكن كلا العمليتان عندئذ من تبدل البيانات فيما بينهما باستخدام الأنبوب دون الحاجة لنظام الملفات.
لا تستخدم جميع الاتصالات بين العمليات لنقل البيانات بينها مع ذلك. في العديد من الحالات، المعلومات التي نحتاج إرسالها رسائل تحكم مثل ”أوقف التنفيذ مؤقتاً“ أو ”تابع التنفيذ“. يقدم يونكس (ولينكس) آلية تُعرَف باسم الإشارات signals، تستطيع العملية من خلالها إرسال إشارة محددة ببساطة (تختارها من قائمة من الإشارات المعرفة مسبقاً) إلى عملية أخرى. المتطلب الوحيد هو معرفة pid العملية الهدف.
هناك آليات أخرى للاتصالات الأكثر تعقيدًا، تسمح للعملية بالسماح لفتح الوصول إلى الذاكرة المخصصة لها، أو مشاركة جزء منها مع العمليات الأخرى. عندئذ يمكن استخدام ذلك الجزء المشترك من الذاكرة المشتركة لنقل البيانات بين العمليات المشتركة عليه.
أخيرًا، يمكن أن تساعد الاتصالات الشبكية بالتواصل بين العمليات؛ يمكن أن توجد هذه العمليات على حواسيب مختلفة، وقد تبعد عن بعضها آلاف الكيلومترات.
من العادي جداً لأي نظام نموذجي مشابه لنظام يونكس أن يستخدم جميع هذه الآليات بدرجات متفاوتة.
تلعب مكتبات الدوال دوراً حيويًا في نظم التشغيل المشابه لنظام يونكس. ليست هذه المكتبات برامج تامة، نظرًا لعدم إمكانية تنفيذها منفردة، لكنها مجموعة من فتات الكود التي يمكن للبرامج القياسية استخدامه. من المكتبات الشائعة، نذكر ما يلي:
مكتبة C القياسية (glibc)، التي تحوي الوظائف الأساسية مثل دوال فتح الملفات أو الاتصالات الشبكية، وغيرها مما يسهل التفاعل مع النواة؛
المكتبات الرسومية، Gtk+ وQt، تسمح للعديد من البرامج بإعادة استخدام العناصر الرسومية التي توفرها؛
مكتبة libpng، التي تسمح بتحميل، وتفسير وحفظ الصور بصيغة PNG.
بفضل هذه المكتبات، تستطيع البرامج إعادة استخدام الكود. يصبح تطوير البرامج أبسط، لأن عدة تطبيقات تستطيع استخدام الدوال نفسها. بما أن تطوير المكتبات يتم بأيد أشخاص مختلفين عادة، فإن التطوير الكلي للنظام أقرب إلى فلسفة يونكس التاريخية.
بالإضافة إلى ذلك، غالباً ما يُشَار إلى هذه المكتبات على أنها ”مكتبات مشتركة“، لأن النواة تستطيع تحميلها إلى الذاكرة مرة واحدة فقط، حتى لو كانت عدة عمليات تستخدم المكتبة نفسها في الوقت ذاته. يسمح هذا بتوفير الذاكرة، مقارنة مع الحالة (النظرية) النقيضة لها حيث يتم تحميل كود المكتبة بعدد العمليات التي تستخدمها.