خيط (حاسوب)
في المعلوماتية والحوسبة، الخيط (بالإنجليزية: Thread) أو سلسلة أو شريط التعليمات (بالإنجليزية: thread of execution) أو الخيوط الحاسوبية (بالإنجليزية: Threads) [1] هو عبارة عن مجموعة من التعليمات التي تشكل مساراً لتنفيذ العملية وبما أنه مجرد مسار فإنه لا يحتاج لموارد خاصة به حيث أنه يستخدم موارد العملية ذاتها. تجعل الخيوط البرنامج الحاسوبي يبدو وكأنه يقوم بأكثر من مهمة بشكل متزامن، لكن إذا كانت وحدة المعالجة المركزية بأكثر من نواة فانه يقوم بعمل تزامن حقيقي، فعلى سبيل المثال يمكن للبرنامج الإبقاء على واجهة المستخدم المرئية تتفاعل مع المستخدم على الرغم من قيامه بمهمة أخرى كالاتصال بمخدم. تتميز الخيوط عن العمليات بشكل عام في طريقة إنشاء سلسلة التعليمات وطريقة مشاركتها للمصادر وأسلوب تنفيذ المعالج لها بشكل مختلف عن العمليات لكن هذه الفوارق في النهاية تختلف حسب نظام التشغيل.
يمكن تنفيذ خيوط تعليمات متعددة بشكل متوازٍ على نفس المعالج وهذا ما يدعى بالتنفيذ المتعدد للخيوط (بالإنجليزية: multithreading) ويحدث عن طريق تعدد المهام computer multitasking أو ما يدعى بتجزئة الوقت time slicing وحيث يقوم معالج مركزي بالتبديل بين سلاسل التعليمات المختلفة. (ضمن هذا المفهوم التنفيذ ليس متزامنا بالنسبة لمعالج واحد لكننا نعتبره تزامنا مزيفا لأن التبديل يتم بسرعة كبيرة تعطينا انطباع بوهم التزامن)، بالمقابل يمكننا انجاز تزامن حقيقي عن طريق الاستعانة بحاسوب متعدد المعالجات أو معالجات متعددة الأنوية .
في الوقت الراهن، العديد من أنظمة التشغيل تدعم تجزئة الزمن وتعدد المهام، أو التنفيذ متعدد المعالجات multiprocessor threading عن طريق منسق عمليات scheduler. تمكن نوى أنظمة التشغيل المبرمجين من التعامل مع عدة سلاسل تعليمات عن طريق واجهة استدعاءات النظام system call. بعض التطبيقات لهذا الموضوع يدعى سلسلة تعليمات النواة kernel thread حيث تكون العمليات الخفيفة lightweight process أنماطا خاصة من سلاسل تعليمات النواة والتي تتشارك بنفس الحالة ونفس المعلومات. ويبقى المبرمجون قادرين على تطبيق سَلسَلة التعليمات threading عن طريق المؤقتات، الإشارات، أو وسائل أخرى لتفسير تسلسل تنفيذ التعليمات وبالتالي الحصول على تجزئة زمنية جيدة. وهذا ما يدعى أحيانا : سلاسل تعليمات مجال المستخدم user-space threads.في أغلب أنظمة التشغيل لايتم تنفيذ سلاسل تعليمات المستخدم الا عبر سلسلة تعليمات النواة.
علاقة سلاسل مجال المستخدم وسلاسل تعليمات النواة:هناك اربع أنواع من العلاقات تربط النوعين من السلاسل وهي كالتالي.
- واحد إلى متعدد: في هذا النوع من العلاقات يرتبط كل تشعب نواة باكثر من تشعب مستخدم. تتميز باستغلال تشعبات النواة لكنها في نفس الوقت تتسبب في الضغط على تشعبات النواة، يستخدم هذا النوع في أنظمة جرين سولاريس، وجنو.
- واحد لواحد: في هذا النوع من العلاقات يرتبط كل تشعب من تشعبات المستخدم بتشعب واحد فقط من تشعبات النواة، يتضح لنا انه لو ان هناك تشعب واحد من تشعبات النواة تعطل فان تشعب المستخدم الذي كان متصلا به لن ينففذ ابداً.
- متعدد لمتعدد: هذا النوع من العلاقات تقوم كل مجموعة من تشعبات النواة بإدارة مجموعة من تشعبات المستخدم.
- نمط المستويين: يستخدم هذا النوع من العلاقات هجين من النوعين السابقين بحيث يسمح بعلاقات واحد لواحد ومتعدد لمتعدد، هذا النوع هو الأكثر استخداما حالياً
هناك ثلاث مكتبات أساسية للتشعبات أو السلاسل : (1) PThreads: وهي اختصار لل POSIX Threads وتستخدم في يونكس وماكنتوش وغيرهما كما تسمح باستخدام سلاسل على مستوى النواة أو على مستوى المستخدم. (2) Win32 Threads : وهي المستخدمة في أنظمة تشغيل ويندوز "النوافذ" ولا تسمح للمستخدم في التعامل مع تشعبات " سلاسل " النواة وانما تتوفر له هذه السلاسل في مجال المستخدم فقط. (3) Java Threads : وهي خاصة ببرامج لغة الجافا وتقوم بإنشاء سلاسل خاصة بكل برنامج على حدة.
في بعض الأحيان يستخدمون مصطلح سلسلة تعليمات من اجل شفرة مجزأة threaded code وهو نمط من الشفرات البرمجية يتألف بالكامل من استدعاءات لأقسام برمجية subroutine.
في الغالب نحن معتادون على تعدد المهام في نظام التشغيل والسماحية لعمل أكثر من برنامج في وقت واحد.
البرامج متعددة الخيوط (بالإنجليزية: Multithreaded programs) تأخذ فكرة تعدد المهام عن طريق اخذها في مستوى أقل، فكل برنامج فردي يظهر عدة مهام في نفس الوقت وكل مهمه تسمى خيط (حاسوب). تستطيع البرامج تشغيل أكثر من خيط (حاسوب) في نفس الوقت وهي اختصار لـ خيط التحكم
والبرامج التي تستطيع تشغيل أكثر من خيط حاسوبي في كل مره تسمى متعددة الخيوط الحاسوبية.
الخيوط المتعددة والعمليات المتعددة
الفرق بين الخيوط المتعددة (بالإنجليزية: multiple threaded) والعمليات المتعددة (بالإنجليزية: multiple processes).
عندما تكون كل عمليه لديها وضعيه متكامله من المتغيرات متغير (علم الحاسوب)
threads تشاركها نفس المعلومات، وهذا قد يشكل خطرًا. مع ذلك مشاركة المتغيرات تجعل الاتصال بين الخيوط threads أسهل وأفضل للبرمجة من الاتصال بين العمليات.
في بعض انظمة التشغيل threads تكون من "lightweight " أكثر من العمليات processes
Multithreading كالمستعرض يقوم بلحظات تحميل أكثر من صوره في نفس الوقت وخادم الشبكة لابد من ان يكون قادر على مزامنة طلب المستخدم.
وإذا اطلعنا على GUI كل منها يحمل thread منفصل يجمع الحدث ليراه المستخدم من بيئة تشغيل المضيف
الخيط
إذا نظرنا في برنامج لا يستخدم الخيوط الحاسوبيه المتعدده multiple threads
يصعب على المستخدم ان يؤدي عدة مهام في هذا البرنامج اما إذا كان هناك برنامج
يستخدم separate threads سنجد سهولة في عمل البرنامج.
دالة thread.sleep لا تنشأ داله جديدة بل هي دالة ثابته في مصفوفة خيط (حاسوب)
بشكل مؤقت توقّف عمل النشاط الذي يستخدم الـ خيط (حاسوب) الحالي
حالات الخيوط Thread states
ممكن ان يكون في واحده من هذه الحالات
- New
- Runnable
- Block
- Waiting
- Time waiting
- Terminated
لتحديد حالة الـ thread الحالي، دالة getState()
تقوم بتحديد حالة الخيط الحالي
الخيوط الجديدة New Threads
عندما تنشآ thread بأداة التشغيل new مثال: new Thread(r) - the thread is not running yet هنا الخيط لم يتم تشغيله بعد، وهذا يعني ان البرنامج لم ينفذ الشفرة (codes). هناك كميه معينه من الحسابات التي تحتاج ان تنتهي قبل تشغيل الـ خيط (thread)
الخيوط القابلة للتنفيذ Runnable Threads
عندما تنفذ دالة start، الخيط الحاسوبي (thread) يكون في حالة runnable state
تعتمد runnable state على نظام التشغيل في العمل. عندما يعمل الخيط thread ليس من الضروري ان يبقى قيد التشغيل، ولكن يستحق التشغيل إذا كان هناك الكثير من الـ running threads وتوقفت لسبب فهنا تأتي الفرصة للخيوط الاخرى بالعمل. تفاصيل الخيوط threads تعتمد على الخدمة التي يوفرها نظام التشغيل. نظام المنظم scheduler system يعطي runnable thread جزء من الوقت ليؤدي مهامه. عندما نختار الـ thread التالي نظام التشغيل يأخذ في الحسبان اولوية الـthread
الخيوط المحظورة والمنتظرة Blocked and Waiting Threads
عندما يكون الخيط محظور (blocked) أو في الانتظار (waiting). هو مؤقتًا غير فعال لاينفّذ اي شفره ويستهلك مصادر أقل ويعتمد ايضا على thread scheduler لاعادة التشغيل وهذه التفاصيل تعتمد على كيفة الوصول إلى الحالة الغير مفعله. عندما يحاول thread ان يكتسب كائن محظور ( lock) لايتضمن حظره على java.util.concurrent library . الـ thread يصبح غير محظور ( unblocked) عندما تكون كل الخيوط threads تنازلت عن الحظر و thread scheduler يسمح لهذه الخيوط ان تمسك بهذا الكائن. عندما ينتظر الخيط خيط اخر لينبه منظم الخيوط ( thread scheduler) لحاله معينه، يدخل في حالة الانتظار وهذا يحدث عن طريق نداء دالة Object.wait or Thread.wait أو عن طريق انتظار lock أو condition في java.util.concurrent library الكثير من الدوال تحتوي على parameters غير ثابته خارج الوقت timeout.
مناداتها يسبب للخيط (thread)ان يدخل في حاله timed waiting
وهذه الحالة تستمر حتى نفاذ الوقت أو ان تتلقى المنبه الصحيح دوال timeout تتضمن Threas.sleep و timed version of
Object.wait, Thread.join, lock.tryLock and Condition.await
يمكن ان يتنقل الـ الخيط من حاله لاخرى عندما يكون الخيط محظور أو في الانتظار وايضا عندما يخرج من البرنامج يأتي خيط آخر ينظم التشغيل.
الخيوط المنتهية Terminated Threads
يقطع الــthread لسبب من هذه الاسباب:
- يموت بشكل طبيعي لان دالة التشغيل تخرج بشكل عادي
- يموت فجأه إذا uncaught Exception قطع دالة التشغيل
يمكن قتل الـ Thread بتنفيذ دالة stop وهذه الدالة throws ThreadDeath error تلقي كائن يقتل الـ thread
خواص الخيوط Thread Properties
في لغة البرمجة كل خيط له اولويه وكل خيط يورّث اولويه للخيط الذي ينشأه. ويمكن زياده أو انقاص اولوية اي خيط عن طريق دالة setPriority تستطيع ضبط الاولويه لأي قيمه بين
MIN_PRIORITY (معرفه كـ 1 في Thread class )
و MAX_PRIORITY معرفه كـ 10 NORM_PRIORITY معرف كـ 5.
كلما اتيحت الفرصة لمنظم الخيوط ان يختار خيط جديد يفضل ذا اولويه عاليه.
اولويات الخيوط هي highly system dependent, عندما تعتمد الآله الفعليه على تطبيق الخيط لبرنامج المضيف الذي
يحتوي على خيط أو أكثر من مستويات الاولويه
مثال: Windows يحمل 7 مستويات للاولويه. بعض اولويات الجافا تشير إلى نفس مستوى نظام التشغيل في The Sun JVM for Linux كل الخيوط تحتوي على نفس المستوى
الخيوط الخفية Daemon Threads
تستطيع تحويل الخيط أو thread إلى daemon thread بمناداة دالة
t.setDaemon(true);
وظيفته الوحيده هي خدمة الغير، مثال: timer thread وظيفته يرسل الدقّات المعتاده للساعة للخيوط الاخرى أو الخيط الذي ينظف catche من البقايا القديمه. الآله الفعليه virtual machine تخرج إذا كانت كل الخيوط Daemon Threads
لانه لامعنى لعمل البرنامج إذا كانت كل الخيوط Daemon
مراجع
- Horstmann, Cay S., 1959- Core Java Volume 1 Fundamentals 8th edition
- بوابة برمجة الحاسوب
- بوابة تقنية المعلومات
- بوابة علم الحاسوب