Adam Ebrahim نشر 28 مايو 2021 أرسل تقرير نشر 28 مايو 2021 أقوم بالتعلم حول تعدد المهام في بايثون وبدأت بمكتبة threading، وأصبح يمكنني أن أقوم بعمل أكثر من thread ولكن لا أعرف كيف أقوم بإيقاف thread معين. وهل يجب أن أقوم التاأكد مما إذا كان الـ thread يقوم بعمل أمر حيوي مثل إستخدام critical resource. كيف أقوم بإنهاء thread قيد التشغيل بطريقة آمنة؟ اقتباس
1 Nuhla Almasri نشر 29 مايو 2021 أرسل تقرير نشر 29 مايو 2021 نعم يوجد طريقة و هي كالتالي : import sys import trace import threading #هنا نعرف صنف من نوع Thread class KThread(threading.Thread): """هنا يرث الصنف Thread""" def __init__(self, *args, **keywords): threading.Thread.__init__(self, *args, **keywords) self.killed = False def start(self): """ دالة لتعريق بدأ thread """ self.__run_backup = self.run self.run = self.__run # Force the Thread to install our trace. threading.Thread.start(self) def __run(self): """دالة لتشغيل التعقب لهذا ال thread.""" sys.settrace(self.globaltrace) self.__run_backup() self.run = self.__run_backup def globaltrace(self, frame, why, arg): if why == 'call': return self.localtrace else: return None def localtrace(self, frame, why, arg): if self.killed: if why == 'line': raise SystemExit() return self.localtrace # هنا الدالة التي تقوم بقتله def kill(self): self.killed = True ------------------------------------------------------------------------ #طريقة الإستعمال ------------------------------------------------------------------------ #إن كما في ملف آحر علينا إستيراد الملف الذي قمنا بخلقه from KThread import * #نعرف دالة جديدة وخذخ الدالة ستقوم بعمل دوران بشكل طبيعي def func(): print 'Function started' for i in xrange(1000000): pass print 'Function finished' #هنا نعرف متغير من الصنف الذي خلقناه للتحكم بال thread # نعطيقه الدالة ليقوم بتعقب الthread #الخاص بها A = KThread(target=func) # نقوم بتشغيل الدالة عن طريق Start A.start() #هنا فقط لتاخير نهاية البرنامج for i in xrange(1000000): pass #ثم هنا نقوم بقتله A.kill() print 'End of main program' Output: Function started 1 اقتباس
1 Ali Haidar Ahmad نشر 17 سبتمبر 2021 أرسل تقرير نشر 17 سبتمبر 2021 نعم يمكن، لكنها فكرة سيئة وقد تؤدي بك إلى العديد من المشاكل. لكن إليك بعض الطرق: قتل النيسب "Thread" من خلال تعريف flag بحيث عند رفعه يتم إيقافه: في الكود التالي، سنعرف علم (flag) وبمجرد أن نقوم برفعه ينتهي تنفيذ الدالة run ويمكن قتل النيسبth1 باستخدام th1.join. import time import threading as th def myfunc (): while True: print('The thread is still working') # نجعل العلم متحول عام لكي تكون التغيرات عليه عامة أي مرئية global flag #يتم إيقاف النيسب True إذا تم رفع العلم أي إذا كان if flag: break # في البداية نجعل العلم غير مرفوع flag = False # نعرف أول نيسب # النيسب يقوم بتنفيذ الدالة السابقة th1 = th.Thread(target = myfunc ) # تشغيل النيسب th1.start() time.sleep(1) # هنا مثلاً نقوم برفع العلم ليتم إيقافه stop_threads = True th1.join() print('thread killed') الطريقة الثانية هي إثارة استثناء في النيسب، من خلال استخدام الدالة PyThreadState_SetAsyncExc: في الكود التالي بمجرد استدعاء الدالة myexception سيتم إنهاء الدالة myfunc لأنه عندما يظهر الاستثناء سينتقل التحكم في البرنامج خارج كتلة try ويتم إنهاء الدالة. بعد ذلك نقوم باستخدام join لقتل النيسب. وفي حالة لم نقوم باستدعاء دالة رفع الاستثناء سيتم تنفيذ myfunc بدون توقف ولن يتم استدعاء Join لقتل النيسب. import threading from ctypes.pythonapi import PyThreadState_SetAsyncExc import time import ctypes # نيسب مع استثناء class exception(threading.Thread): def __init__(self, name): threading.Thread.__init__(self) self.name = name # التابع الهدف def myfunc(self): try: while True: print('is running ' + self.name) finally: print('is over') # دالة لإرجاع رقم الثريد def ID_(self): if hasattr(self, '_thread_id'): return self._thread_id for id, thread in threading._active.items(): if thread is self: return id # دالة لرفع استثناء def myexception(self): id = self.ID_() e = PyThreadState_SetAsyncExc(id, ctypes.py_object(SystemExit)) if e > 1: PyThreadState_SetAsyncExc(id, 0) # طباعة رسالة تعبر عن أنه تمت إثارة الاستقناء print('failure') th = exception('thr') # نمرر اسم النيسب # تشغيله th.start() time.sleep(1) # استدعاء دالة رفع الاستثناء ليتم إيقافه th.myexception() th.join() 1 اقتباس
السؤال
Adam Ebrahim
أقوم بالتعلم حول تعدد المهام في بايثون وبدأت بمكتبة threading، وأصبح يمكنني أن أقوم بعمل أكثر من thread ولكن لا أعرف كيف أقوم بإيقاف thread معين. وهل يجب أن أقوم التاأكد مما إذا كان الـ thread يقوم بعمل أمر حيوي مثل إستخدام critical resource.
كيف أقوم بإنهاء thread قيد التشغيل بطريقة آمنة؟
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.