تقلل الخيوط بشكل كبير من وقت تنفيذ البرنامج. تعرف على كيفية تنفيذ الترابط في بايثون.

يعد وقت التنفيذ أحد المقاييس الشائعة لكفاءة البرنامج. كلما كان وقت التنفيذ أسرع كلما كان البرنامج أفضل. الخيوط هي تقنية تسمح للبرنامج بأداء مهام أو عمليات متعددة في وقت واحد.

سوف تتعلم كيفية استخدام لغة Python المدمجة خيوط وحدة و الميزات المتزامنة وحدة. توفر كلتا الوحدتين طرقًا بسيطة لإنشاء سلاسل الرسائل وإدارتها

أهمية الخيوط

يقلل الترابط مقدار الوقت الذي يستغرقه البرنامج لإكمال المهمة. إذا كانت المهمة تحتوي على عدة مهام مستقلة ، فيمكنك استخدام الترابط لتشغيل المهام بشكل متزامن ، مما يقلل من وقت انتظار البرنامج حتى تنتهي مهمة واحدة قبل الانتقال إلى التالية.

على سبيل المثال ، برنامج يقوم بتنزيل ملفات صور متعددة من الإنترنت. يمكن لهذا البرنامج استخدام خيوط التحميل لتنزيل الملفات بالتوازي بدلاً من واحد في كل مرة. هذا يلغي الوقت الذي سيتعين على البرنامج انتظاره حتى تكتمل عملية تنزيل ملف واحد قبل الانتقال إلى الملف التالي.

البرنامج الأولي قبل الخيوط

تمثل الوظيفة في البرنامج التالي مهمة. تتمثل المهمة في إيقاف تنفيذ البرنامج مؤقتًا لمدة ثانية واحدة. يقوم البرنامج باستدعاء الوظيفة مرتين ومن ثم إنشاء مهمتين. ثم يقوم بحساب الوقت المستغرق لتشغيل البرنامج بالكامل ثم يعرضه على الشاشة.

instagram viewer

يستورد وقت

start_time = time.perf_counter ()

defيوقف():
مطبعة("النوم ثانية واحدة ...")
وقت النوم(1)
مطبعة("انتهى النوم ...")

يوقف()
يوقف()
finish_time = time.perf_counter ()
مطبعة(و'منتهي في {round (finish_time - start_time،) 2)} ثانية (ثوان) ")

يوضح الإخراج أن البرنامج استغرق 2.01 ثانية للتنفيذ. استغرقت كل مهمة ثانية واحدة واستغرق تنفيذ باقي التعليمات البرمجية 0.01 ثانية.

يمكنك استخدام الترابط لتنفيذ كلا المهمتين في نفس الوقت. سيستغرق تنفيذ كلا المهمتين ثانية واحدة.

تنفيذ خيوط باستخدام وحدة الترابط

لتعديل التعليمات البرمجية الأولية لتنفيذ مؤشر الترابط ، قم باستيراد ملف خيوط وحدة. إنشاء اثنين من المواضيع ، موضوع_1 و موضوع_2 باستخدام خيط فصل. اتصل ب يبدأ طريقة على كل موضوع لبدء تنفيذه. اتصل ب ينضم الطريقة على كل مؤشر ترابط لانتظار اكتمال تنفيذها قبل تنفيذ بقية البرنامج.

يستورد وقت
يستورد خيوط
start_time = time.perf_counter ()

defيوقف():
مطبعة("النوم ثانية واحدة ...")
وقت النوم(1)
مطبعة("انتهى النوم ...")

thread_1 = خيوط. الخيط (الهدف = وقفة)
thread_2 = خيط. الخيط (الهدف = وقفة)

thread_1.start ()
thread_2.start ()

thread_1.join ()
thread_2.join ()

finish_time = time.perf_counter ()
مطبعة(و'منتهي في {round (finish_time - start_time،) 2)} ثانية (ثوان) ")

سيقوم البرنامج بتشغيل كلا الموضوعين في نفس الوقت. سيؤدي ذلك إلى تقليل الوقت المستغرق لإنجاز كلتا المهمتين.

يوضح الإخراج أن الوقت المستغرق لتشغيل نفس المهام يبلغ حوالي ثانية. هذا هو نصف الوقت الذي استغرقه البرنامج الأولي.

تنفيذ خيوط المعالجة باستخدام الوحدة النمطية concurrent.futures

شهد Python 3.2 تقديم المستقبل المتزامن وحدة. توفر هذه الوحدة واجهة عالية المستوى لتنفيذ المهام غير المتزامنة باستخدام مؤشرات الترابط. يوفر طريقة أبسط لتنفيذ المهام بالتوازي.

لتعديل البرنامج الأولي لاستخدام مؤشر الترابط ، قم باستيراد الوحدة النمطية concurrent.features. استخدم ال ThreadPoolExecutor فئة من الوحدة النمطية concurrent.futures لإنشاء مجموعة من المواضيع. تقديم يوقف تعمل على حمام السباحة مرتين. ال يُقدِّم طريقة إرجاع أ مستقبل الذي يمثل نتيجة استدعاء الوظيفة.

كرر على الآجلة وطباعة نتائجهم باستخدام ملف نتيجة طريقة.

يستورد وقت
يستورد المستقبل المتزامن

start_time = time.perf_counter ()

defيوقف():
مطبعة("النوم ثانية واحدة ...")
وقت النوم(1)
يعود"انتهى النوم ..."

مع المستقبل المتزامن. ThreadPoolExecutor () مثل المنفذ:
النتائج = [تقديم المنفذ (إيقاف مؤقت) ل _ في يتراوح(2)]
ل F في concurrent.futures.as_completed (النتائج):
طباعة (f.result ())

finish_time = time.perf_counter ()

مطبعة(و'منتهي في {round (finish_time - start_time،) 2)} ثانية (ثوان) ")

تهتم الوحدة النمطية concurrent.features ببدء سلاسل الرسائل والانضمام إليها نيابةً عنك. هذا يجعل كودك أنظف.

الإخراج مطابق لوحدة الترابط. تعد وحدة الترابط مفيدة للحالات البسيطة التي تحتاج فيها إلى تشغيل عدد قليل من الخيوط بالتوازي. من ناحية أخرى ، تعد وحدة concurrent.futures النمطية مفيدة للحالات الأكثر تعقيدًا حيث تحتاج إلى تشغيل العديد من المهام بشكل متزامن.

استخدام الترابط في سيناريو العالم الحقيقي

يؤدي استخدام الخيوط لتشغيل البرنامج أعلاه إلى تقليل الوقت بمقدار ثانية واحدة. في العالم الحقيقي ، توفر الخيوط مزيدًا من الوقت. قم بإنشاء برنامج يقوم بتنزيل الصور من الإنترنت. ابدأ ب خلق بيئة افتراضية جديدة. قم بتشغيل الأمر التالي في المحطة لتثبيت ملف الطلبات مكتبة:

طلبات تثبيت النقطة

ستسمح لك مكتبة الطلبات بإرسال طلبات HTTP. استيراد مكتبة الطلبات ومكتبة الوقت.

يستورد الطلبات
يستورد وقت

قم بإنشاء قائمة عناوين URL للصور التي ترغب في تنزيلها. دعهم لا يقل عن عشرة حتى تتمكن من ملاحظة اختلاف كبير عند تنفيذ مؤشر الترابط.

img_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]

حلقة فوق القائمة من عناوين URL التي تقوم بتنزيل كل صورة في نفس المجلد الذي يحتوي على مشروعك. اعرض الوقت المستغرق لتنزيل الصور عن طريق طرح وقت الانتهاء من وقت البدء.

start_time = time.perf_counter ()
ل img_url في img_urls:
img_bytes = request.get (img_url) .content
img_name = img_url.split ('/')[3]
img_name = F'{img_name}.jpg '
مع فتح (img_name ، "wb") مثل img_ ملف:
img_file.write (img_bytes)
مطبعة(F'{img_name} تم تنزيله... ")
finish_time = time.perf_counter ()
مطبعة(و'منتهي في {finish_time - start_time} ثواني)

يستغرق البرنامج حوالي 22 ثانية لتنزيل 12 صورة. قد يختلف الأمر بالنسبة لك لأن الوقت المستغرق لتنزيل الصور يعتمد أيضًا على سرعة الإنترنت لديك.

قم بتعديل البرنامج لاستخدام مؤشر الترابط باستخدام وحدة concurrent.features. بدلاً من التكرار الحلقي ، استخدم دالة. هذه هي الوظيفة التي ستمررها إلى ملف المنفذ مثال.

يستورد الطلبات
يستورد وقت
يستورد المستقبل المتزامن

img_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]

start_time = time.perf_counter ()

defdownload_image(img_url):
img_bytes = request.get (img_url) .content
img_name = img_url.split ('/')[3]
img_name = F'{img_name}.jpg '
مع فتح (img_name ، "wb") مثل img_ ملف:
img_file.write (img_bytes)
مطبعة(F'{img_name} تم تنزيله... ")

مع المستقبل المتزامن. ThreadPoolExecutor () مثل المنفذ:
خريطة المنفذ (download_image، img_urls)

finish_time = time.perf_counter ()

مطبعة(و'منتهي في {finish_time-start_time} ثواني)

بعد إدخال الخيوط. الوقت يقلل بشكل كبير. استغرق الأمر 4 ثوان فقط لإكمال تنفيذ البرنامج.

سيناريوهات مناسبة للتخيط

بعض السيناريوهات المناسبة للترابط هي:

  • I / O مهام ملزمة: إذا كان البرنامج يقضي معظم الوقت في انتظار اكتمال عمليات الإدخال أو الإخراج. يمكن أن يؤدي الترابط إلى تحسين الأداء من خلال السماح بتنفيذ المهام الأخرى أثناء انتظار اكتمال عمليات الإدخال / الإخراج.
  • تجريف على شبكة الإنترنت: يتضمن تجريف الويب إجراء طلبات HTTP وتحليل استجابات HTML. يساعد الترابط في تسريع العملية من خلال السماح لك بتقديم طلبات متعددة في وقت واحد.
  • المهام المرتبطة بوحدة المعالجة المركزية: يمكن أن يساعد الترابط في تحسين الأداء من خلال السماح بتنفيذ مهام متعددة بشكل متوازٍ.

تعرف على الخيوط باللغات الأخرى

Python ليست اللغة الوحيدة التي تدعم الترابط. تدعم معظم لغات البرمجة شكلاً من أشكال الترابط. من المهم أن تتعرف على تنفيذ الخيوط بلغات أخرى. يزودك هذا بالمهارات اللازمة للتعامل مع السيناريوهات المختلفة التي قد يتم فيها تطبيق خيوط المعالجة.