# تشعب (حوسبة)

في المعلوماتية والحوسبة، التشعب (بالإنجليزية: Thread)‏ أو النَيْسَب أو شريط التعليمات (بالإنجليزية: thread of execution)‏ أو التشعبات الحاسوبية (بالإنجليزية: Threads)‏ هو عبارة عن مجموعة من التعليمات التي تشكل مساراً لتنفيذ العملية وبما أنه مجرد مسار فإنه لا يحتاج لموارد خاصة به حيث أنه يستخدم موارد العملية ذاتها. تجعل التشعبات البرنامج الحاسوبي يبدو وكأنه يقوم بأكثر من مهمة بشكل متزامن، لكن إذا كانت وحدة المعالجة المركزية بأكثر من نواة فانه يقوم بعمل تزامن حقيقي، فعلى سبيل المثال يمكن للبرنامج الإبقاء على واجهة المستخدم المرئية تتفاعل مع المستخدم على الرغم من قيامه بمهمة أخرى كالاتصال بمخدم. تتميز التشعبات عن العمليات بشكل عام في طريقة إنشاء سلسلة التعليمات وطريقة مشاركتها للمصادر وأسلوب تنفيذ المعالج لها بشكل مختلف عن العمليات لكن هذه الفوارق في النهاية تختلف حسب نظام التشغيل.
يمكن تنفيذ تشعبات تعليمات متعددة بشكل متوازٍ على نفس المعالج وهذا ما يدعى بالتنفيذ المتعدد للتشعبات (بالإنجليزية: 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

## مراجع

* ↑ معجم المصطلحات المعلوماتية (بالعربية والإنجليزية)، دمشق: الجمعية العلمية السورية للمعلوماتية، 2000، ص. 531، OCLC:47938198، QID:Q108408025
* ↑ Horstmann, Cay S., 1959- Core Java Volume 1 Fundamentals 8th edition
* بوابة برمجة الحاسوب
* بوابة تقانة المعلومات
* بوابة علم الحاسوب