الفرق بين المراجعتين لصفحة: «Ruby/Thread»
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة وتدقيق. |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: | <noinclude>{{DISPLAYTITLE:الصنف <code>Thread</code> في روبي}}</noinclude> | ||
[[تصنيف: Ruby]] | [[تصنيف: Ruby]] | ||
[[تصنيف: Ruby Class]] | |||
[[تصنيف: Ruby Thread]] | [[تصنيف: Ruby Thread]] | ||
المهام الفرعية (Threads، وتدعى "الخيوط" أيضًا) هي الطريقة التي تنفذ بها روبي البرمجة المتزامنة (concurrent programming). | المهام الفرعية (Threads، وتدعى "الخيوط" أيضًا) هي الطريقة التي تنفذ بها روبي البرمجة المتزامنة (concurrent programming). | ||
البرامج التي تتطلب تنفيذ عدة مهام فرعية يمكنها استخدام الصنف <code>Thread</code>. على سبيل المثال، يمكننا إنشاء مهمة فرعية جديدة منفصلة عن المهمة الرئيسية باستخدام <code>[[Ruby/Thread/new|new]]</code>.<syntaxhighlight lang="ruby">thr = Thread.new { puts "Whats the big deal" }</syntaxhighlight>ثم يمكننا إيقاف تنفيذ المهمة الفرعية الرئيسية مؤقتًا إلى حين إنتهاء المهمة الفرعية خاصتنا باستخدام التابع <code>[[Ruby/Thread/join|join]]</code>:<syntaxhighlight lang="ruby">thr.join #=> "Whats the big deal"</syntaxhighlight>في حال عدم استدعاء | البرامج التي تتطلب تنفيذ عدة مهام فرعية يمكنها استخدام الصنف <code>Thread</code>. على سبيل المثال، يمكننا إنشاء مهمة فرعية جديدة منفصلة عن المهمة الرئيسية باستخدام التابع <code>[[Ruby/Thread/new|new]]</code>.<syntaxhighlight lang="ruby">thr = Thread.new { puts "Whats the big deal" }</syntaxhighlight>ثم يمكننا إيقاف تنفيذ المهمة الفرعية الرئيسية مؤقتًا إلى حين إنتهاء المهمة الفرعية خاصتنا باستخدام التابع <code>[[Ruby/Thread/join|join]]</code>:<syntaxhighlight lang="ruby">thr.join #=> "Whats the big deal"</syntaxhighlight>في حال عدم استدعاء التابع [[Ruby/Thread/join|<code>join</code>]] قبل انتهاء المهمة الرئيسية، فسيتم إنهاء جميع المهام الفرعية الأخرى، بما في ذلك المهمة الفرعية التي أنشأناها. | ||
بدلاً من ذلك، يمكنك استخدام [[Ruby/Array|مصفوفة]] للتعامل مع عدة مهام فرعية في وقت واحد كما في المثال التالي:<syntaxhighlight lang="ruby">threads = [] | بدلاً من ذلك، يمكنك استخدام [[Ruby/Array|مصفوفة]] للتعامل مع عدة مهام فرعية في وقت واحد كما في المثال التالي:<syntaxhighlight lang="ruby">threads = [] | ||
سطر 29: | سطر 30: | ||
p Thread.current[:foo] # => nil | p Thread.current[:foo] # => nil | ||
}.resume | }.resume | ||
}.join</syntaxhighlight>يستخدم هذا المثال معامل الفهرسة | }.join</syntaxhighlight>يستخدم هذا المثال معامل الفهرسة [[Ruby/Thread/index operator|<code>[]</code>]] لأجل الاستخلاص، ويستخدم معامل التعيين [[Ruby/Thread/index operator-3D|<code>=[]</code>]] لأجل تعيين [[Ruby/Fiber|ليف]] محلي (fiber-locals)؛ يمكنك أيضًا استخدام التابع <code>[[Ruby/Thread/keys|keys]]</code> لإنشاء قائمة بالألياف المحلية لمهمة فرعية معينة، أو التابع <code>[[Ruby/Thread/key-3F|key?]]</code> للتحقق من وجود ألياف محلية. | ||
يمكن الوصول إلى المتغيرات المحلية في المهمة الفرعية (thread-locals) من أي مكان في نطاق تلك المهمة. إليك المثال التالي:<syntaxhighlight lang="ruby">Thread.new{ | يمكن الوصول إلى المتغيرات المحلية في المهمة الفرعية (thread-locals) من أي مكان في نطاق تلك المهمة. إليك المثال التالي:<syntaxhighlight lang="ruby">Thread.new{ | ||
سطر 44: | سطر 45: | ||
يمكن أيضًا استخدام التابع <code>[[Ruby/Thread/thread variables|thread_variables]]</code> لإنشاء قائمة بجميع المتغيرات المحلية في مهمة فرعية (thread-locals)، والتابع <code>[[Ruby/Thread/thread variable-3F|thread_variable?]]</code> للتحقق من وجود متغير محلي معين في مهمة فرعية. | يمكن أيضًا استخدام التابع <code>[[Ruby/Thread/thread variables|thread_variables]]</code> لإنشاء قائمة بجميع المتغيرات المحلية في مهمة فرعية (thread-locals)، والتابع <code>[[Ruby/Thread/thread variable-3F|thread_variable?]]</code> للتحقق من وجود متغير محلي معين في مهمة فرعية. | ||
==معالجة | ==معالجة الاستثناءات== | ||
يمكن لأي مهمة فرعية إطلاق استثناء باستخدام تابع النسخة <code>[[Ruby/Thread/raise|raise]]</code>، والذي يعمل بطريقة مشابهة للتابع <code>[[Ruby/Kernel/raise|Kernel.raise]]</code>. | يمكن لأي مهمة فرعية إطلاق [[Ruby/Exception|استثناء]] باستخدام تابع النسخة <code>[[Ruby/Thread/raise|raise]]</code>، والذي يعمل بطريقة مشابهة للتابع <code>[[Ruby/Kernel/raise|Kernel.raise]]</code>. | ||
من الجدير بالذكر أنّ الاستثناءات التي تُطلق من أي مهمة الفرعية، باستثناء الرئيسية (main thread)، التي تعتمد على <code>[[Ruby/Thread/abort on exception|abort_on_exception]]</code>. قيمة هذا الخيار الافتراضية هي <code>false</code>، مما يعني أن أي استثناء غير مُعالَج سيؤدي إلى إنهاء المهمة الفرعية بصمت عند الانتظار سواءً من <code>[[Ruby/Thread/join|join]]</code> أو من <code>[[Ruby/Thread/value|value]]</code>. يمكنك تغيير هذا الإعداد الافتراضي عبر استدعاء <code>[[Ruby/Thread/abort on exception-3D|abort_on_exception=]] true</code> ، أو من خلال إعطاء <code>[[Ruby/Thread/DEBUG|DEBUG]]</code> القيمة <code>true</code>. | من الجدير بالذكر أنّ الاستثناءات التي تُطلق من أي مهمة الفرعية، باستثناء الرئيسية (main thread)، التي تعتمد على <code>[[Ruby/Thread/abort on exception|abort_on_exception]]</code>. قيمة هذا الخيار الافتراضية هي <code>false</code>، مما يعني أن أي استثناء غير مُعالَج سيؤدي إلى إنهاء المهمة الفرعية بصمت عند الانتظار سواءً من <code>[[Ruby/Thread/join|join]]</code> أو من <code>[[Ruby/Thread/value|value]]</code>. يمكنك تغيير هذا الإعداد الافتراضي عبر استدعاء <code>[[Ruby/Thread/abort on exception-3D|abort_on_exception=]] true</code>، أو من خلال إعطاء التابع <code>[[Ruby/Thread/DEBUG|DEBUG]]</code> القيمة <code>true</code>. | ||
مع إضافة تابع الصنف <code>[[Ruby/Thread/handle interrupt|handle_interrupt]]</code>، يمكنك الآن معالجة الاستثناءات بشكل غير متزامن بالمهام الفرعية. | مع إضافة تابع الصنف <code>[[Ruby/Thread/handle interrupt|handle_interrupt]]</code>، يمكنك الآن معالجة الاستثناءات بشكل غير متزامن بالمهام الفرعية. | ||
سطر 53: | سطر 54: | ||
توفر روبي عدة وسائل لجدولة المهام الفرعية في البرنامج. الطريقة الأولى هي باستخدام تابع الصنف <code>[[Ruby/Thread/stop|stop]]</code>، لوضع المهمة الفرعية الحالية في حالة نوم، وجدولة عملية تنفيذ مهمة فرعية أخرى. | توفر روبي عدة وسائل لجدولة المهام الفرعية في البرنامج. الطريقة الأولى هي باستخدام تابع الصنف <code>[[Ruby/Thread/stop|stop]]</code>، لوضع المهمة الفرعية الحالية في حالة نوم، وجدولة عملية تنفيذ مهمة فرعية أخرى. | ||
بمجرد أن تصبح المهمة الفرعية في حالة نوم، يمكنك استخدام | بمجرد أن تصبح المهمة الفرعية في حالة نوم، يمكنك استخدام التابع <code>[[Ruby/Thread/wakeup|wakeup]]</code> لجعلها متاحة للجدولة. | ||
يمكنك أيضًا استخدام التابع <code>[[Ruby/Thread/pass|pass]]</code>، والذي يحاول تمرير التنفيذ إلى مهمة فرعية أخرى؛ مسألة استبدال المهمة الفرعية قيد التشغيل تتعلق بنظام التشغيل المستخدم. وينطبق الأمر ذاته على التابع <code>[[Ruby/Thread/priority|priority]]</code>، والذي يتيح لك الطلب من مُجدوِل المهام الفرعية (thread scheduler) إعطاء الأسبقية لمهام فرعية معينة عند التنفيذ. يعتمد هذا التابع أيضًا على نظام التشغيل، وقد يُتجاهَل في بعض الأنظمة. | يمكنك أيضًا استخدام التابع <code>[[Ruby/Thread/pass|pass]]</code>، والذي يحاول تمرير التنفيذ إلى مهمة فرعية أخرى؛ مسألة استبدال المهمة الفرعية قيد التشغيل تتعلق بنظام التشغيل المستخدم. وينطبق الأمر ذاته على التابع <code>[[Ruby/Thread/priority|priority]]</code>، والذي يتيح لك الطلب من مُجدوِل المهام الفرعية (thread scheduler) إعطاء الأسبقية لمهام فرعية معينة عند التنفيذ. يعتمد هذا التابع أيضًا على نظام التشغيل، وقد يُتجاهَل في بعض الأنظمة. | ||
سطر 60: | سطر 61: | ||
يُعيد مستوى التصحيح في المهمة الفرعية (thread debug level). | يُعيد مستوى التصحيح في المهمة الفرعية (thread debug level). | ||
===[[Ruby/Thread/DEBUG-3D|<code>DEBUG=</code>]]=== | ===[[Ruby/Thread/DEBUG-3D|<code>DEBUG=</code>]]=== | ||
يعيّن عند استدعائه بالشكل <code>DEBUG = num</code> قيمة مستوى تصحيح <nowiki/> | يعيّن عند استدعائه بالشكل <code>DEBUG = num</code> قيمة مستوى تصحيح <nowiki/>المهمة الفرعية (thread debug level) إلى القيمة <code>num</code>. | ||
===[[Ruby/Thread/abort on exception|<code>abort_on_exception</code>]]=== | ===[[Ruby/Thread/abort on exception|<code>abort_on_exception</code>]]=== | ||
يُعيد حالة الشرط العام "المقاطعة عند حدوث استثناء؟" (abort on exception). | يُعيد حالة الشرط العام "المقاطعة عند حدوث استثناء؟" (abort on exception). | ||
سطر 89: | سطر 90: | ||
===[[Ruby/Thread/report on exception|<code>report_on_exception</code>]]=== | ===[[Ruby/Thread/report on exception|<code>report_on_exception</code>]]=== | ||
يعيد حالة "التبليغ عند الاستثناء" (report on exception). | يعيد حالة "التبليغ عند الاستثناء" (report on exception). | ||
===[[Ruby/Thread/report on exception-3D|<code>report_on_exception=</code>]]=== | |||
يضبط عند استدعائه بالشكل <code>report_on_exception= boolean</code> حالة "التبليغ عند الاستثناء" (report on exception). | يضبط عند استدعائه بالشكل <code>report_on_exception= boolean</code> حالة "التبليغ عند الاستثناء" (report on exception). | ||
===[[Ruby/Thread/start|<code>start</code>]]=== | ===[[Ruby/Thread/start|<code>start</code>]]=== | ||
يشبه التابع <code>[[Ruby/Thread/new|new]]</code> بشكل أساسي إلا أنه عند اشتقاق صنف فرعي (subclassed) من <code> | يشبه التابع <code>[[Ruby/Thread/new|new]]</code> بشكل أساسي إلا أنه عند اشتقاق صنف فرعي (subclassed) من <code>Thread</code>، فإنَّ استدعاء <code>start</code> في ذلك الصنف الفرعي لن يستدعي تابع الصنف الفرعي<code>initialize</code>. | ||
===[[Ruby/Thread/stop|<code>stop</code>]]=== | ===[[Ruby/Thread/stop|<code>stop</code>]]=== | ||
يوقف تنفيذ المهمة الفرعية الحالية، ويضعها في حالة "نوم" (sleep)، ويُجدوٍل (schedules) تنفيذ مهمة فرعية أخرى. | يوقف تنفيذ المهمة الفرعية الحالية، ويضعها في حالة "نوم" (sleep)، ويُجدوٍل (schedules) تنفيذ مهمة فرعية أخرى. | ||
سطر 98: | سطر 99: | ||
== تزوابع النسخة العامة (Public Instance Methods) == | == تزوابع النسخة العامة (Public Instance Methods) == | ||
===<code rel="mw:WikiLink" | ===<code rel="mw:WikiLink" title="Ruby/Thread/index operator" href="Ruby/Thread/index operator">[[Ruby/Thread/index operator|[]]]</code>=== | ||
يُعيد قيمة متغير محلي [[Ruby/Fiber|الليف]] fiber) local variable، أو [[Ruby/Fiber|الليف]] الأصلي للمهمة الفرعية الحالية إن لم يكن المتغير موجودًا داخل [[Ruby/Fiber|ليف]]) باستخدام إما رمز أو [[Ruby/String|سلسلة نصية]]. | |||
===[[Ruby/Thread/index operator-3D|<code>[] | ===[[Ruby/Thread/index operator-3D|<code>=[]</code>]]=== | ||
يعيّن عندما يُستدعى بالشكل <code>thr[sym] = obj</code> قيمة المتغير <code>sym</code> محلي [[Ruby/Fiber|الليف]] (fiber-local variable)، باستخدام إما الرمز أو [[Ruby/String|السلسلة النصية]] <code>obj</code> أو ينشئها. | |||
===[[Ruby/Thread/abort on exception|<code>abort_on_exception</code>]]=== | ===[[Ruby/Thread/abort on exception|<code>abort_on_exception</code>]]=== | ||
يُعيد | يُعيد حالة الشرط المحلي (thread-local) "المقاطعة عند حدوث استثناء؟" (abort on exception) في المهمة الفرعية التي استُدعي معها. | ||
===[[Ruby/Thread/abort on exception-3D|<code>abort_on_exception=</code>]]=== | ===[[Ruby/Thread/abort on exception-3D|<code>abort_on_exception=</code>]]=== | ||
عند | يضبط عند استدعائه بالشكل <code>abort_on_exception= boolean</code> حالة الشرط المحلي "المقاطعة عند حدوث استثناء؟" (abort on exception) إلى القيمة المنطقية <code>boolean</code>. | ||
===[[Ruby/Thread/add trace func|<code>add_trace_func</code>]]=== | ===[[Ruby/Thread/add trace func|<code>add_trace_func</code>]]=== | ||
يضيف <code> | يضيف عملية (كائنًا من النوع <code>[[Ruby/Proc|Proc]]</code>) كمعالج للتعقب (tracing) إلى المهمة الفرعية التي استدعيت معه. | ||
===[[Ruby/Thread/alive-3F|<code>alive?</code>]]=== | ===[[Ruby/Thread/alive-3F|<code>alive?</code>]]=== | ||
يتحقق إن كانت المهمة الفرعية التي استُدعي معها قيد التشغيل أو نائمة. | |||
===[[Ruby/Thread/backtrace|<code>backtrace</code>]]=== | ===[[Ruby/Thread/backtrace|<code>backtrace</code>]]=== | ||
يُعيد | يُعيد التعقب (backtrace) الحالي للمهمة فرعية التي استدعي معها. | ||
===[[Ruby/Thread/backtrace locations|<code>backtrace_locations</code>]]=== | ===[[Ruby/Thread/backtrace locations|<code>backtrace_locations</code>]]=== | ||
يُعيد | يُعيد مكدس التنفيذ (execution stack) الخاص بالمهمة الفرعية على شكل <nowiki/>[[Ruby/Array|مصفوفة]] تحتوي على كائنات التعقب (backtrace location objects). | ||
=== <code>[[Ruby/Thread/fetch|fetch]]</code> === | |||
(لم يوثَّق بعد.) | |||
===[[Ruby/Thread/exit|<code>exit</code>]]=== | ===[[Ruby/Thread/exit|<code>exit</code>]]=== | ||
ينهي | ينهي المهمة الفرعية قيد التشغيل حاليًا، ويُجدوِل (schedules) مهمة فرعية أخرى ليتم تشغيلها. | ||
===[[Ruby/Thread/group|<code>group</code>]]=== | ===[[Ruby/Thread/group|<code>group</code>]]=== | ||
يُعيد | يُعيد مجموعة الخيوط <code>[[Ruby/ThreadGroup|ThreadGroup]]</code> التي تحتوي على المهمة الفرعية المعطاة، أو يُعيد <code>nil</code> إذا لم تكن المهمة الفرعية عضوًا في أي مجموعة. | ||
===[[Ruby/Thread/inspect|<code>inspect</code>]]=== | ===[[Ruby/Thread/inspect|<code>inspect</code>]]=== | ||
يعيد اسم ورقم تعريف وحالة المهمة الفرعية على هيئة سلسلة نصية. | |||
===[[Ruby/Thread/join|<code>join</code>]]=== | ===[[Ruby/Thread/join|<code>join</code>]]=== | ||
عند | يوقف عند استدعائه تنفيذ المهمة الفرعية المُستدعيَة (calling thread)، وبدء تنفيذ المهمة الفرعية التي استُدعي معها. | ||
===[[Ruby/Thread/key-3F|<code>key?</code>]]=== | ===[[Ruby/Thread/key-3F|<code>key?</code>]]=== | ||
يتحقق إن كانت <nowiki/>[[Ruby/String|السلسلة النصية]] أو الرمز المعطى موجود على هيئة متغير محلي <nowiki/>[[Ruby/Fiber|الليف]](fiber-local variable). | |||
===[[Ruby/Thread/keys|<code>keys</code>]]=== | ===[[Ruby/Thread/keys|<code>keys</code>]]=== | ||
يُعيد | يُعيد [[Ruby/Array|مصفوفة]] من أسماء المتغيرات محلية [[Ruby/Fiber|الليف]] (على هيئة رموز). | ||
===[[Ruby/Thread/kill|<code>kill</code>]]=== | ===[[Ruby/Thread/kill|<code>kill</code>]]=== | ||
ينهي المهمة الفرعية التي استُدعي معها، ثم يجدول مهمة فرعية أخرى لتنفيذها. | |||
===[[Ruby/Thread/name|<code>name</code>]]=== | ===[[Ruby/Thread/name|<code>name</code>]]=== | ||
يعيد | يعيد اسم المهمة الفرعية. | ||
===[[Ruby/Thread/name-3D|<code>name=</code>]]=== | ===[[Ruby/Thread/name-3D|<code>name=</code>]]=== | ||
يعين | يعين اسم المهمة الفرعية التي استدعيت معه إلى الاسم المُمرَّر إليه. | ||
===[[Ruby/Thread/pending interrupt-3F|<code>pending_interrupt?</code>]]=== | ===[[Ruby/Thread/pending interrupt-3F|<code>pending_interrupt?</code>]]=== | ||
يتحقق مما إذا كان طابور الانتظار غير المتزامن فارغًا أم لا. | يتحقق مما إذا كان طابور الانتظار غير المتزامن فارغًا أم لا. | ||
===[[Ruby/Thread/priority|<code>priority</code>]]=== | ===[[Ruby/Thread/priority|<code>priority</code>]]=== | ||
يُعيد | يُعيد أولوية المهمة الفرعية التي استدعيت معه. | ||
===[[Ruby/Thread/priority-3D|<code>priority=</code>]]=== | ===[[Ruby/Thread/priority-3D|<code>priority=</code>]]=== | ||
يعين <code>priority= | يعين عند استدعائه بالشكل <code>priority= integer</code> أولوية المهمة الفرعية التي استدعيت معه إلى القيمة <code>integer</code>. | ||
===[[Ruby/Thread/raise|<code>raise</code>]]=== | ===[[Ruby/Thread/raise|<code>raise</code>]]=== | ||
يطلق | يطلق استثناء من مهمة فرعية معينة. | ||
===[[Ruby/Thread/report on exception|<code>report_on_exception</code>]]=== | ===[[Ruby/Thread/report on exception|<code>report_on_exception</code>]]=== | ||
يعيد | يعيد حالة "التبليغ عند حصول استثناء" (report on exception) للمهمة الفرعية المحلية. | ||
===[[Ruby/Thread/report on exception-3D|<code>report_on_exception=</code>]]=== | ===[[Ruby/Thread/report on exception-3D|<code>report_on_exception=</code>]]=== | ||
يضبط عند استدعائه بالشكل <code>report_on_exception= boolean</code> حالة "التبليغ عند حصول استثناء" (report on exception) للمهمة الفرعية المحلية المعطاة إلى القيمة <code>boolean</code>. | |||
===[[Ruby/Thread/run|<code>run</code>]]=== | ===[[Ruby/Thread/run|<code>run</code>]]=== | ||
يوقظ | يوقظ المهمة الفرعية، ويجعلها متاحة للجدولة. | ||
===[[Ruby/Thread/safe level|<code>safe_level</code>]]=== | ===[[Ruby/Thread/safe level|<code>safe_level</code>]]=== | ||
يُعيد | يُعيد المستوى الآمن للمهمة فرعية. | ||
===[[Ruby/Thread/set trace func|<code>set_trace_func</code>]]=== | ===[[Ruby/Thread/set trace func|<code>set_trace_func</code>]]=== | ||
يجعل <code> | يجعل الكائن <code>[[Ruby/Proc|proc]]</code> معالجًا للتعقب (handler for tracing) في المهمة الفرعية، أو يعطل التعقب إن كان مُرِّرت القيمة <code>nil</code> بدلًا من ذلك الكائن. | ||
===[[Ruby/Thread/status|<code>status</code>]]=== | ===[[Ruby/Thread/status|<code>status</code>]]=== | ||
يعيد | يعيد حالة المهمة الفرعية. | ||
===[[Ruby/Thread/stop-3F|<code>stop?</code>]]=== | ===[[Ruby/Thread/stop-3F|<code>stop?</code>]]=== | ||
يتحقق إن كانت المهمة الفرعية ميتة أو نائمة. | |||
===[[Ruby/Thread/terminate|<code>terminate</code>]]=== | ===[[Ruby/Thread/terminate|<code>terminate</code>]]=== | ||
ينهي | ينهي [[Ruby/Thread|المهمة الفرعية]] التي استدعيت معه ويُجدوِل مهمة فرعية أخرى ليتم تشغيلها. | ||
===[[Ruby/Thread/thread variable-3F|<code>thread_variable?</code>]]=== | ===[[Ruby/Thread/thread variable-3F|<code>thread_variable?</code>]]=== | ||
يتحقق إن كانت <nowiki/>[[Ruby/String|السلسلة النصية]] أو الرمز المعطى موجودًا كمتغير محلي للمهمة الفرعية (thread-local variable). | |||
===[[Ruby/Thread/thread variable get|<code>thread_variable_get</code>]]=== | ===[[Ruby/Thread/thread variable get|<code>thread_variable_get</code>]]=== | ||
يُعيد | يُعيد قيمة المتغير المحلي للمهمة الفرعية (thread local variable) الذي تم تعيينه. | ||
===[[Ruby/Thread/thread variable set|<code>thread_variable_set</code>]]=== | ===[[Ruby/Thread/thread variable set|<code>thread_variable_set</code>]]=== | ||
يعين | يعين قيمة متغير محلي ذي اسم محدَّد في المهمة الفرعية (thread local) إلى قيمة معيَّنة. | ||
===[[Ruby/Thread/thread variables|<code>thread_variables</code>]]=== | ===[[Ruby/Thread/thread variables|<code>thread_variables</code>]]=== | ||
يُعيد | يُعيد [[Ruby/Array|مصفوفة]] من أسماء المتغيرات المحلية في المهمة الفرعية (thread-local) على شكل رموز. | ||
===[[Ruby/Thread/to s|<code>to_s</code>]]=== | ===[[Ruby/Thread/to s|<code>to_s</code>]]=== | ||
يعيد < | يعيد اسم ومعرِّف وحالة مهمة فرعية على هيئة <nowiki/>[[Ruby/String|سلسلة نصية]]. | ||
===[[Ruby/Thread/value|<code>value</code>]]=== | ===[[Ruby/Thread/value|<code>value</code>]]=== | ||
ينتظر | ينتظر اكتمال المهمة الفرعية، باستخدام التابع <code>[[Ruby/Thread/join|join]]</code> ثم يُعيد قيمتها، أو يطلق الاستثناء الذي أنهى المهمة الفرعية. | ||
===[[Ruby/Thread/wakeup|<code>wakeup</code>]]=== | ===[[Ruby/Thread/wakeup|<code>wakeup</code>]]=== | ||
يوقظ مهمة فرعية ويجعلها متاحة للجدولة، ولكن قد تظل معطلة في مجرى الإدخال/الإخراج (I/O). | |||
==مصادر== | ==مصادر== | ||
*[http://ruby-doc.org/core-2.5.1/Thread.html صفحة الصنف Thread في توثيق روبي الرسمي.] | *[http://ruby-doc.org/core-2.5.1/Thread.html صفحة الصنف Thread في توثيق روبي الرسمي.] |
المراجعة الحالية بتاريخ 08:51، 6 ديسمبر 2018
المهام الفرعية (Threads، وتدعى "الخيوط" أيضًا) هي الطريقة التي تنفذ بها روبي البرمجة المتزامنة (concurrent programming).
البرامج التي تتطلب تنفيذ عدة مهام فرعية يمكنها استخدام الصنف Thread
. على سبيل المثال، يمكننا إنشاء مهمة فرعية جديدة منفصلة عن المهمة الرئيسية باستخدام التابع new
.
thr = Thread.new { puts "Whats the big deal" }
ثم يمكننا إيقاف تنفيذ المهمة الفرعية الرئيسية مؤقتًا إلى حين إنتهاء المهمة الفرعية خاصتنا باستخدام التابع join
:
thr.join #=> "Whats the big deal"
في حال عدم استدعاء التابع join
قبل انتهاء المهمة الرئيسية، فسيتم إنهاء جميع المهام الفرعية الأخرى، بما في ذلك المهمة الفرعية التي أنشأناها.
بدلاً من ذلك، يمكنك استخدام مصفوفة للتعامل مع عدة مهام فرعية في وقت واحد كما في المثال التالي:
threads = []
threads << Thread.new { puts "Whats the big deal" }
threads << Thread.new { 3.times { puts "Threads are fun!" } }
بعد إنشاء عدد من المهام الفرعية، سننتظر إلى أن تنتهي جميعها بالتتابع.
threads.each { |thr| thr.join }
تهيئة المهام الفرعية
لإنشاء مهام فرعية جديدة، توفر روبي عدة توابع لذلك هي: new
و start
و fork
. يجب تمرير كتلة مع كل هذه التوابع، وإلا سيُطلق الاستثناء ThreadError
.
عند اشتقاق أصناف فرعية (subclasses) من Thread
، فسيتم تجاهل التابع initialize
الخاص بصنفك الفرعي من قبل التوابع start
و fork
. لذلك تأكد من استدعاء المتغير super
في التابع initialize
خاصتك.
إنهاء مهمة الفرعية
توفر روبي مجموعة متنوعة من الطرق لإنهاء المهام الفرعية. ينهي (أو يقتل) التابع kill
مثلًا المهمة الفرعية المعطاة:
thr = Thread.new { ... }
Thread.kill(thr) # sends exit() to thr
أو يمكنك استخدام تابع النسخة exit
، أو أحد الأسماء البديلة له وهي kill
و terminate
.
thr.exit
حالة مهمة الفرعية
توفر روبي عددًا من من توابع النسخة (instance methods) لاستخلاص حالة مهمة فرعية معينة. للحصول على سلسلة نصية تحتوي حالة المهمة الفرعية الحالية، استخدم التابع status
:
thr = Thread.new { sleep }
thr.status # => "sleep"
thr.exit
thr.status # => false
يمكنك أيضًا استخدام التابع alive?
للتحقق مما إذا كانت المهمة الفرعية قيد التشغيل أو نائمة، أو التابع stop?
للتحقق مما إذا كانت المهمة الفرعية ميتة أو نائمة.
متغيرات ونطاق مهمة الفرعية
نظرًا لكون المهام الفرعية تُنشأ بواسطة الكتل، فستُطبَّق القواعد نفسها على كتل روبي الأخرى فيما يتعلق بنطاق (scope) المتغيرات. المتغيرات المحلية التي تم إنشاؤها داخل هذه الكتلة لا يمكن الوصول إليها إلا من داخل هذه المهمة الفرعية.
الألياف المحلية مقابل الخيوط المحلية
يحتوي كل ليف (fiber) على نطاق خاص به لتخزين العناصر المعيّنة من المعامل []
. عندما تعيِّن ليفًا محليًّا (fiber-local)، فلن يمكن الوصول إليه إلا من داخل ذلك الليف. المثال التالي يوضح ذلك:
Thread.new {
Thread.current[:foo] = "bar"
Fiber.new {
p Thread.current[:foo] # => nil
}.resume
}.join
يستخدم هذا المثال معامل الفهرسة []
لأجل الاستخلاص، ويستخدم معامل التعيين =[]
لأجل تعيين ليف محلي (fiber-locals)؛ يمكنك أيضًا استخدام التابع keys
لإنشاء قائمة بالألياف المحلية لمهمة فرعية معينة، أو التابع key?
للتحقق من وجود ألياف محلية.
يمكن الوصول إلى المتغيرات المحلية في المهمة الفرعية (thread-locals) من أي مكان في نطاق تلك المهمة. إليك المثال التالي:
Thread.new{
Thread.current.thread_variable_set(:foo, 1)
p Thread.current.thread_variable_get(:foo) # => 1
Fiber.new{
Thread.current.thread_variable_set(:foo, 2)
p Thread.current.thread_variable_get(:foo) # => 2
}.resume
p Thread.current.thread_variable_get(:foo) # => 2
}.join
يمكنك أن ترى أن المتغير :foo
محلي المهمة الفرعية قد وصل إلى نطاق الليف، ثم تم تغييره إلى القيمة 2
في نهاية المهمة الفرعية.
هذا المثال يستخدم التابع thread_variable_set
لإنشاء مهمة فرعية جديدة، ويستخدم thread_variable_get
للرجوع إليها.
يمكن أيضًا استخدام التابع thread_variables
لإنشاء قائمة بجميع المتغيرات المحلية في مهمة فرعية (thread-locals)، والتابع thread_variable?
للتحقق من وجود متغير محلي معين في مهمة فرعية.
معالجة الاستثناءات
يمكن لأي مهمة فرعية إطلاق استثناء باستخدام تابع النسخة raise
، والذي يعمل بطريقة مشابهة للتابع Kernel.raise
.
من الجدير بالذكر أنّ الاستثناءات التي تُطلق من أي مهمة الفرعية، باستثناء الرئيسية (main thread)، التي تعتمد على abort_on_exception
. قيمة هذا الخيار الافتراضية هي false
، مما يعني أن أي استثناء غير مُعالَج سيؤدي إلى إنهاء المهمة الفرعية بصمت عند الانتظار سواءً من join
أو من value
. يمكنك تغيير هذا الإعداد الافتراضي عبر استدعاء abort_on_exception= true
، أو من خلال إعطاء التابع DEBUG
القيمة true
.
مع إضافة تابع الصنف handle_interrupt
، يمكنك الآن معالجة الاستثناءات بشكل غير متزامن بالمهام الفرعية.
الجدولة (Scheduling)
توفر روبي عدة وسائل لجدولة المهام الفرعية في البرنامج. الطريقة الأولى هي باستخدام تابع الصنف stop
، لوضع المهمة الفرعية الحالية في حالة نوم، وجدولة عملية تنفيذ مهمة فرعية أخرى.
بمجرد أن تصبح المهمة الفرعية في حالة نوم، يمكنك استخدام التابع wakeup
لجعلها متاحة للجدولة.
يمكنك أيضًا استخدام التابع pass
، والذي يحاول تمرير التنفيذ إلى مهمة فرعية أخرى؛ مسألة استبدال المهمة الفرعية قيد التشغيل تتعلق بنظام التشغيل المستخدم. وينطبق الأمر ذاته على التابع priority
، والذي يتيح لك الطلب من مُجدوِل المهام الفرعية (thread scheduler) إعطاء الأسبقية لمهام فرعية معينة عند التنفيذ. يعتمد هذا التابع أيضًا على نظام التشغيل، وقد يُتجاهَل في بعض الأنظمة.
توابع الصنف العامة
DEBUG
يُعيد مستوى التصحيح في المهمة الفرعية (thread debug level).
DEBUG=
يعيّن عند استدعائه بالشكل DEBUG = num
قيمة مستوى تصحيح المهمة الفرعية (thread debug level) إلى القيمة num
.
abort_on_exception
يُعيد حالة الشرط العام "المقاطعة عند حدوث استثناء؟" (abort on exception).
abort_on_exception=
يضبط عند استدعائه بالشكل abort_on_exception= boolean
حالة الشرط العام "المقاطعة عند حدوث استثناء؟" (abort on exception) إلى القيمة المنطقية boolean
.
current
يُعيد المهمة الفرعية المُنفّذة حاليًّا.
exclusive
يغلف الكتلة المعطاة في دالة الآلة الافتراضية العامة (VM-global)Mutex.synchronize
، ثم يعيد قيمة الكتلة.
exit
ينهي المهمة الفرعية قيد التشغيل، ويُجدول مهمة فرعية أخرى ليتم تشغيلها.
fork
ينشئ عملية فرعية جديدة بشكل مكافئ للتابع new.
handle_interrupt
يغير توقيت المقاطعة غير المتزامنة (asynchronous interrupt timing).
kill
ينهي المهمة الفرعية المعطاة.
list
يُعيد مصفوفة من المهام الفرعية العاملة أو المتوقفة.
main
يُعيد المهمة الفرعية الرئيسية.
new
ينشئ مهمة فرعية جديدة تقوم بتنفيذ الكتلة المعطاة.
pass
يعطي إلى مُجدوِل المهمة الفرعية تلميحًا لتمرير التنفيذ إلى مهمة فرعية أخرى.
pending_interrupt?
يتحقق مما إذا كان طابور الانتظار غير المتزامن فارغًا أم لا.
report_on_exception
يعيد حالة "التبليغ عند الاستثناء" (report on exception).
report_on_exception=
يضبط عند استدعائه بالشكل report_on_exception= boolean
حالة "التبليغ عند الاستثناء" (report on exception).
start
يشبه التابع new
بشكل أساسي إلا أنه عند اشتقاق صنف فرعي (subclassed) من Thread
، فإنَّ استدعاء start
في ذلك الصنف الفرعي لن يستدعي تابع الصنف الفرعيinitialize
.
stop
يوقف تنفيذ المهمة الفرعية الحالية، ويضعها في حالة "نوم" (sleep)، ويُجدوٍل (schedules) تنفيذ مهمة فرعية أخرى.
تزوابع النسخة العامة (Public Instance Methods)
[]
يُعيد قيمة متغير محلي الليف fiber) local variable، أو الليف الأصلي للمهمة الفرعية الحالية إن لم يكن المتغير موجودًا داخل ليف) باستخدام إما رمز أو سلسلة نصية.
=[]
يعيّن عندما يُستدعى بالشكل thr[sym] = obj
قيمة المتغير sym
محلي الليف (fiber-local variable)، باستخدام إما الرمز أو السلسلة النصية obj
أو ينشئها.
abort_on_exception
يُعيد حالة الشرط المحلي (thread-local) "المقاطعة عند حدوث استثناء؟" (abort on exception) في المهمة الفرعية التي استُدعي معها.
abort_on_exception=
يضبط عند استدعائه بالشكل abort_on_exception= boolean
حالة الشرط المحلي "المقاطعة عند حدوث استثناء؟" (abort on exception) إلى القيمة المنطقية boolean
.
add_trace_func
يضيف عملية (كائنًا من النوع Proc
) كمعالج للتعقب (tracing) إلى المهمة الفرعية التي استدعيت معه.
alive?
يتحقق إن كانت المهمة الفرعية التي استُدعي معها قيد التشغيل أو نائمة.
backtrace
يُعيد التعقب (backtrace) الحالي للمهمة فرعية التي استدعي معها.
backtrace_locations
يُعيد مكدس التنفيذ (execution stack) الخاص بالمهمة الفرعية على شكل مصفوفة تحتوي على كائنات التعقب (backtrace location objects).
fetch
(لم يوثَّق بعد.)
exit
ينهي المهمة الفرعية قيد التشغيل حاليًا، ويُجدوِل (schedules) مهمة فرعية أخرى ليتم تشغيلها.
group
يُعيد مجموعة الخيوط ThreadGroup
التي تحتوي على المهمة الفرعية المعطاة، أو يُعيد nil
إذا لم تكن المهمة الفرعية عضوًا في أي مجموعة.
inspect
يعيد اسم ورقم تعريف وحالة المهمة الفرعية على هيئة سلسلة نصية.
join
يوقف عند استدعائه تنفيذ المهمة الفرعية المُستدعيَة (calling thread)، وبدء تنفيذ المهمة الفرعية التي استُدعي معها.
key?
يتحقق إن كانت السلسلة النصية أو الرمز المعطى موجود على هيئة متغير محلي الليف(fiber-local variable).
keys
يُعيد مصفوفة من أسماء المتغيرات محلية الليف (على هيئة رموز).
kill
ينهي المهمة الفرعية التي استُدعي معها، ثم يجدول مهمة فرعية أخرى لتنفيذها.
name
يعيد اسم المهمة الفرعية.
name=
يعين اسم المهمة الفرعية التي استدعيت معه إلى الاسم المُمرَّر إليه.
pending_interrupt?
يتحقق مما إذا كان طابور الانتظار غير المتزامن فارغًا أم لا.
priority
يُعيد أولوية المهمة الفرعية التي استدعيت معه.
priority=
يعين عند استدعائه بالشكل priority= integer
أولوية المهمة الفرعية التي استدعيت معه إلى القيمة integer
.
raise
يطلق استثناء من مهمة فرعية معينة.
report_on_exception
يعيد حالة "التبليغ عند حصول استثناء" (report on exception) للمهمة الفرعية المحلية.
report_on_exception=
يضبط عند استدعائه بالشكل report_on_exception= boolean
حالة "التبليغ عند حصول استثناء" (report on exception) للمهمة الفرعية المحلية المعطاة إلى القيمة boolean
.
run
يوقظ المهمة الفرعية، ويجعلها متاحة للجدولة.
safe_level
يُعيد المستوى الآمن للمهمة فرعية.
set_trace_func
يجعل الكائن proc
معالجًا للتعقب (handler for tracing) في المهمة الفرعية، أو يعطل التعقب إن كان مُرِّرت القيمة nil
بدلًا من ذلك الكائن.
status
يعيد حالة المهمة الفرعية.
stop?
يتحقق إن كانت المهمة الفرعية ميتة أو نائمة.
terminate
ينهي المهمة الفرعية التي استدعيت معه ويُجدوِل مهمة فرعية أخرى ليتم تشغيلها.
thread_variable?
يتحقق إن كانت السلسلة النصية أو الرمز المعطى موجودًا كمتغير محلي للمهمة الفرعية (thread-local variable).
thread_variable_get
يُعيد قيمة المتغير المحلي للمهمة الفرعية (thread local variable) الذي تم تعيينه.
thread_variable_set
يعين قيمة متغير محلي ذي اسم محدَّد في المهمة الفرعية (thread local) إلى قيمة معيَّنة.
thread_variables
يُعيد مصفوفة من أسماء المتغيرات المحلية في المهمة الفرعية (thread-local) على شكل رموز.
to_s
يعيد اسم ومعرِّف وحالة مهمة فرعية على هيئة سلسلة نصية.
value
ينتظر اكتمال المهمة الفرعية، باستخدام التابع join
ثم يُعيد قيمتها، أو يطلق الاستثناء الذي أنهى المهمة الفرعية.
wakeup
يوقظ مهمة فرعية ويجعلها متاحة للجدولة، ولكن قد تظل معطلة في مجرى الإدخال/الإخراج (I/O).