كيف تعمل الخيوط في بايثون، وما هي المخاطر الشائعة الخاصة بخيوط بايثون؟

StackOverflow https://stackoverflow.com/questions/31340

  •  09-06-2019
  •  | 
  •  

سؤال

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

مما يمكنني قوله، يمكن تشغيل مؤشر ترابط واحد فقط في وقت واحد، ويقوم الخيط النشط بالتبديل كل 10 تعليمات أو نحو ذلك؟

أين يوجد تفسير جيد، أو هل يمكنك تقديم واحد؟سيكون من الجيد أيضًا أن تكون على دراية بالمشكلات الشائعة التي تواجهها أثناء استخدام سلاسل الرسائل مع Python.

هل كانت مفيدة؟

المحلول

نعم، بسبب قفل المترجم العالمي (GIL)، لا يمكن تشغيل سوى موضوع واحد في كل مرة.وإليك بعض الروابط التي تحتوي على بعض الأفكار حول هذا الأمر:

من الرابط الأخير اقتباس مثير للاهتمام:

اسمحوا لي أن أشرح ماذا يعني كل ذلك.يتم تشغيل المواضيع داخل نفس الجهاز الظاهري ، وبالتالي تشغيل على نفس الجهاز الفعلي.يمكن أن تعمل العمليات على نفس الآلة المادية أو في آلة فعلية أخرى.إذا قمت بتصنيع تطبيقك حول المواضيع ، فلن تفعل شيئًا للوصول إلى آلات متعددة.لذلك ، يمكنك توسيع نطاق أكبر عدد من النوى على الجهاز المفرد (الذي سيكون عدد قليل مع مرور الوقت) ، ولكن للوصول إلى مقاييس الويب حقًا ، ستحتاج إلى حل مشكلة الجهاز المتعدد على أي حال.

إذا كنت ترغب في استخدام النواة المتعددة، pyprocessing يحدد واجهة برمجة التطبيقات (API) القائمة على العملية للقيام بالتوازي الحقيقي.ال بيب يتضمن أيضًا بعض المعايير المثيرة للاهتمام.

نصائح أخرى

بايثون هي لغة سهلة الاستخدام إلى حد ما، ولكن هناك محاذير.أهم شيء تحتاج إلى معرفته هو قفل المترجم العالمي.وهذا يسمح لموضوع واحد فقط بالوصول إلى المترجم.وهذا يعني شيئين:1) نادرًا ما تجد نفسك تستخدم عبارة القفل في لغة بايثون، و2) إذا كنت ترغب في الاستفادة من الأنظمة متعددة المعالجات، فيجب عليك استخدام عمليات منفصلة.يحرر:يجب أن أشير أيضًا إلى أنه يمكنك وضع بعض التعليمات البرمجية في C/C++ إذا كنت تريد الالتفاف حول GIL أيضًا.

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

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

يوجد أدناه نموذج خيوط أساسي.وسوف تفرخ 20 المواضيع.سوف يقوم كل خيط بإخراج رقم الخيط الخاص به.قم بتشغيله ولاحظ الترتيب الذي تتم طباعته به.

import threading
class Foo (threading.Thread):
    def __init__(self,x):
        self.__x = x
        threading.Thread.__init__(self)
    def run (self):
          print str(self.__x)

for x in xrange(20):
    Foo(x).start()

كما أشرت إلى أن سلاسل بايثون يتم تنفيذها من خلال تقسيم الوقت.هذه هي الطريقة التي يحصلون بها على التأثير "الموازي".

في المثال الخاص بي، تقوم فئة Foo الخاصة بي بتوسيع الخيط، ثم أقوم بتنفيذ ملف run الطريقة، حيث يذهب الكود الذي ترغب في تشغيله في سلسلة رسائل.لبدء الخيط الذي تتصل به start() على كائن مؤشر الترابط، والذي سيتم استدعاءه تلقائيًا run طريقة...

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

استخدم سلاسل الرسائل في بايثون إذا كان العمال الفرديون يقومون بعمليات الإدخال/الإخراج المرتبطة.إذا كنت تحاول التوسع عبر عدة مراكز على جهاز ما، فابحث عن خيار جيد IPC إطار عمل لـ python أو اختر لغة مختلفة.

ملحوظة: أينما أذكر thread أعني على وجه التحديد المواضيع في بيثون حتى يتم ذكر ذلك صراحة.

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

نظرًا لأن إدارة الذاكرة في بايثون ليست آمنة لمؤشر الترابط، فإن كل مؤشر ترابط يتطلب وصولاً حصريًا إلى هياكل البيانات في مترجم بايثون. يتم الحصول على هذا الوصول الحصري من خلال آلية تسمى GIL (قفل المترجم العالمي).

Why does python use GIL?

من أجل منع مؤشرات الترابط المتعددة من الوصول إلى حالة المترجم الفوري في وقت واحد وإتلاف حالة المترجم الفوري.

الفكرة هي كلما تم تنفيذ موضوع (حتى لو كان الموضوع الرئيسي), ، يتم الحصول على GIL وبعد فترة زمنية محددة مسبقًا يتم إصدار GIL بواسطة الخيط الحالي ويتم إعادة تكوينه بواسطة سلسلة أخرى (إن وجدت).

Why not simply remove GIL?

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

لذا فإن تكلفة إزالة GIL يتم سدادها من خلال انخفاض أداء تطبيق واحد مترابط، وهو أمر غير مرغوب فيه أبدًا.

So when does thread switching occurs in python?

يحدث تبديل الخيط عند إصدار GIL. إذن متى يتم إصدار GIL؟هناك سيناريوهان يجب أخذهما بعين الاعتبار.

إذا كان الخيط يقوم بعمليات منضمة لوحدة المعالجة المركزية (معالجة الصور السابقة).

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

في الإصدارات الجديدة، بدلاً من استخدام عدد التعليمات كمقياس لتبديل مؤشر الترابط، يتم استخدام فاصل زمني قابل للتكوين.الفاصل الزمني للتبديل الافتراضي هو 5 مللي ثانية. يمكنك الحصول على الفاصل الزمني للتبديل الحالي باستخدام sys.getswitchinterval().يمكن تغيير هذا باستخدام sys.setswitchinterval()

إذا كان الخيط يقوم ببعض عمليات IO Bound (الوصول إلى نظام الملفات السابق أو
إدخال/إخراج الشبكة)

يتم إصدار GIL عندما يكون مؤشر الترابط في انتظار اكتمال عملية الإدخال والإخراج.

Which thread to switch to next?

ليس لدى المترجم برنامج جدولة خاص به. أي مؤشر ترابط يتم جدولته في نهاية الفاصل الزمني هو قرار نظام التشغيل..

أحد الحلول السهلة لـ GIL هو المعالجة المتعددة وحدة.يمكن استخدامه كبديل لوحدة الترابط ولكنه يستخدم عمليات مترجم فوري متعددة بدلاً من سلاسل الرسائل.ولهذا السبب، هناك حمل أكبر قليلاً من الترابط العادي للأشياء البسيطة ولكنه يمنحك ميزة التوازي الحقيقي إذا كنت في حاجة إليها.كما أنه يتدرج بسهولة إلى أجهزة مادية متعددة.

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

حاول أن تتذكر أنه تم تعيين GIL للاستطلاع بين الحين والآخر لإظهار مظهر المهام المتعددة.يمكن ضبط هذا الإعداد بشكل جيد، لكنني أقترح أنه يجب أن يكون هناك عمل تقوم به الخيوط وإلا فإن الكثير من مفاتيح تبديل السياق سوف تسبب مشاكل.

سأذهب إلى أبعد من ذلك لاقتراح العديد من الآباء على المعالجات ومحاولة الاحتفاظ بالوظائف المشابهة على نفس النواة (العناصر الأساسية).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top