ThreadPoolExecutor
شغّل المهام بالتزامن
ThreadPoolExecutor درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Python Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Python Academy 4 دروس في المجموع.
لماذا نستخدم تجمع خيوط؟
إنشاء الخيوط وانتظار انتهائها يدويًا أمر شاق. تتولى concurrent.futures.ThreadPoolExecutor إدارة تجمع من خيوط العمل نيابةً عنكم، وتعيد النتائج بطريقة منظمة.
from concurrent.futures import ThreadPoolExecutor
def square(n):
return n * n
with ThreadPoolExecutor() as ex:
future = ex.submit(square, 5)
print(future.result())submit وFuture
تجدول submit() استدعاءً وتعيد فورًا كائن Future. وتستدعون .result() عليه للحصول على القيمة، حيث ينتظر حتى تصبح جاهزة.
from concurrent.futures import ThreadPoolExecutor
def greet(name):
return 'hi ' + name
with ThreadPoolExecutor(max_workers=2) as ex:
f1 = ex.submit(greet, 'Ana')
f2 = ex.submit(greet, 'Bob')
print(f1.result())
print(f2.result())map لمدخلات متعددة
تشغّل executor.map(func, iterable) الدالة على كل عنصر بالتزامن، وتنتج النتائج بترتيب المدخلات.
from concurrent.futures import ThreadPoolExecutor
def cube(n):
return n ** 3
with ThreadPoolExecutor() as ex:
results = ex.map(cube, range(5))
print(list(results))التحكم في عدد خيوط العمل
يحدّ max_workers عدد الخيوط التي تعمل في آن واحد. وفي الأعمال المقيّدة بالإدخال والإخراج، يمكنكم استخدام عدد من خيوط العمل يفوق عدد أنوية المعالج.
from concurrent.futures import ThreadPoolExecutor
import time
def io_task(n):
time.sleep(0.05)
return n
start = time.perf_counter()
with ThreadPoolExecutor(max_workers=4) as ex:
print(list(ex.map(io_task, range(4))))
print('ran concurrently')as_completed
ينتج as_completed(futures) كل Future فور انتهائه، بغض النظر عن ترتيب إرساله. وهذا مناسب لمعالجة النتائج فور وصولها.
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
def work(n):
time.sleep(0.01 * (3 - n))
return n
with ThreadPoolExecutor() as ex:
futures = [ex.submit(work, i) for i in range(3)]
for f in as_completed(futures):
print('finished', f.result())معالجة الاستثناءات
إذا رفعت مهمة استثناءً، يُخزَّن الاستثناء في Future الخاص بها ويُعاد رفعه عند استدعاء .result(). أحيطوا ذلك الاستدعاء بكتلة try/except.
from concurrent.futures import ThreadPoolExecutor
def risky(n):
if n == 0:
raise ValueError('cannot be zero')
return 10 // n
with ThreadPoolExecutor() as ex:
f = ex.submit(risky, 0)
try:
print(f.result())
except ValueError as e:
print('caught:', e)التعيين باستخدام عدة وسيطات
تقبل map عدة كائنات قابلة للتكرار وتضمّها في صورة وسيطات، مثل map المضمّنة.
from concurrent.futures import ThreadPoolExecutor
def add(a, b):
return a + b
with ThreadPoolExecutor() as ex:
print(list(ex.map(add, [1, 2, 3], [10, 20, 30])))جمع النتائج في قاموس
من الأنماط الشائعة ربط كل Future بمدخله، حتى تعرفوا أي نتيجة تخص أي مدخل عند استخدام as_completed.
from concurrent.futures import ThreadPoolExecutor, as_completed
def length(word):
return len(word)
words = ['cat', 'tiger', 'ox']
with ThreadPoolExecutor() as ex:
future_to_word = {ex.submit(length, w): w for w in words}
out = {}
for f in as_completed(future_to_word):
out[future_to_word[f]] = f.result()
print(sorted(out.items()))إيقاف التشغيل باستخدام مدير السياق
يؤدي استخدام executor داخل كتلة with إلى استدعاء shutdown() تلقائيًا، مع الانتظار حتى انتهاء جميع المهام المعلّقة.
from concurrent.futures import ThreadPoolExecutor
def job(n):
return n * 2
with ThreadPoolExecutor() as ex:
futures = [ex.submit(job, i) for i in range(3)]
print('all tasks done after the with block')
print([f.result() for f in futures])التحقق من حالة Future
يعرض Future الدالتين .done() و.running()، مما يتيح لكم فحص التقدم من دون حجب التنفيذ.
from concurrent.futures import ThreadPoolExecutor
def quick(n):
return n + 1
with ThreadPoolExecutor() as ex:
f = ex.submit(quick, 41)
result = f.result()
print('done?', f.done())
print('value:', result)متى تستخدمونه؟
يُعدّ ThreadPoolExecutor مثاليًا لكثير من مهام الإدخال والإخراج الصغيرة، مثل استدعاءات HTTP وقراءة الملفات واستعلامات قواعد البيانات. أما الأعمال المقيّدة بالمعالج، فاستخدموا ProcessPoolExecutor بدلًا منه.
from concurrent.futures import ThreadPoolExecutor
urls = ['a', 'b', 'c']
def fetch(u):
return 'fetched ' + u
with ThreadPoolExecutor(max_workers=3) as ex:
for r in ex.map(fetch, urls):
print(r)اختبار سريع
اختبروا مدى فهمكم لـ ThreadPoolExecutor.
مراجعة
لقد تعلّمتم ThreadPoolExecutor:
- تعيد
submit()كائن Future، بينما تعملmap()على عنصر قابل للتكرار بالترتيب. - تعيد
as_completed()كائنات Future عند اكتمالها. - تظهر الاستثناءات من خلال
result(). - تتولى كتلة
withإيقاف التشغيل.
التالي: التوازي الحقيقي باستخدام multiprocessing.
الأسئلة الشائعة
هل درس «ThreadPoolExecutor» مجاني؟
نعم — نص درس «ThreadPoolExecutor» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.
ماذا ستتعلم في «ThreadPoolExecutor»؟
شغّل المهام بالتزامن تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟
لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «ThreadPoolExecutor»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟
نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الخيوط وGIL
- ThreadPoolExecutor
- أساسيات multiprocessing
- مشاركة البيانات بأمان