بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
الجزء الثاني أساسيات ال Threading في بايثون .
هذا الموضوع تكملة الجزء الأول .
https://arfedora.blogspot.com/2018/10/1-threading.html
البداية .
قمت بإنشاء دالة لإضافة رقم واحد ودالة لطرح رقم واحد من قيمة num .
من المفروض أن تكون النتيجة في النهاية صفر لأني من جهة أضفت رقم ثم من جهة أخرى طرحت رقم .
لاكن الذي لم ننتبه له ان بعض اﻷنواع الأولية في بايثون ليست بما يسمى thread safe أي لنفترض أول thread الذي يضيف رقم كان أسرع النتيجة لن تكون معروفة في النهاية قد تكون صفر وقد لا تكون لان أثناء إضافة أو حذف الرقم لا يوجد قفل يمنع thread أخرى من التعديل على القيمة حتى ينتهي ال thread الذي مثلا يضيف رقم من عمله أي ستتداخل الامور .
إذا أردت أن امنع أي thread اخر من التعديل على القيمة حتى ينتهي ال thread الحالي من عمله ممكن ان أستخدم قفل خاص.
acquire تعني بشكل بسيط تفعيل القفل .
ثم بعد التعديل على قيمة num أيضا بشكل بسيط إلغاء تفعيل القفل من خلال release ,
لهذا النتيجة كانت صفر أي مرة يضيف رقم ومرة يطرح رقم من دون أن يتداخلو .
الأفضل ان تقرأ قليلا عن python data types thread safe.
أيضا ممكن الإستعانة ب Queue وهو thread safe وهو طابور (هذا تعريبه) شيء مثل طابور التلاميذ في المدرسة و FIFO أي first in first out أي أول عنصر يدخل إلى الطابور هو أيضا أول عنصر يخرج .
لإدخال عنصر إلى الطابور نستخدم put إخراج عنصر من الطابور نستخدم get .
ممكن أن نقوم بعمل class و نرث Thread ونكتب ما نريد ان يتم تنفيذه داخل وظيفة run ثم عند تشغيل وظيفة start ستقوم بالازم ومنها تشغيل وظيفة run من دون تدخل منا مع الملاحظة سيتوقف ال thread عند إنتهاء عمل run .
قمت بعمل class يأخذ button و spinner ثم داخل run يشغل أمر dnf update لاكن قبل تنفيذ الامر يقوم أولا بإذا صح التعبير إلغاء تفعيل الbutton بشكل مؤقت ثم تشغيل ال spinner ثم بعد الإنتهاء يرجع كل شيء كما كان.
نلاحظ أن البرنامج توقف وخرج بخطأ السبب أن Gtk ليست thread safe بمعنى واجهة البرنامج الرسومية تعمل في Main Thread ومنها ال button و spinner إذا تفاعلنا معهم من خارج ال main Thread قد تتداخل الأمور ويخرج البرنامج بخطأ لهذا يجب أن تطلب من ال main Thread القيام بهذه المهمة كما فعلت في الصورة في الأسفل .
طلبت من خلال GLib.idle_add من ال Main Thread التفاعل مع ال button و ال spinner و ممكن إذا كانو كثر جمعهم في دالة واحدة وتشغيبها من خلال idle_add الإثنين يعملو لا مشكلة .