لماذا تعتبر التزامن بدون قفل مثل هذه الصفقة الكبيرة (في clojure)؟

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

سؤال

قيل لي إن Clojure لديه تزامن بلا مغلق وأن هذا أمر مهم.

لقد استخدمت عددًا من اللغات ، لكنني لم أدرك أنها كانت تؤدي أقفال وراء الكواليس.

لماذا هذه ميزة في clojure (أو بأي لغة لديها هذه الميزة)؟

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

المحلول

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

عادة ما يتم تحقيقها مع أنواع غير قابلة للتغيير. إذا لم يكن من الممكن تعديل أي شيء ، فأنت لا تحتاج حقًا إلى الانتظار حتى يتم تنفيذ شخص آخر معه قبل أن تتمكن من الوصول إليه.

نصائح أخرى

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

deadlocks. أو أن تكون أكثر صحة نقصهم.

واحدة من أكبر المشكلات في معظم اللغات هي أن تنتهي بالكمال الذي:

  1. الجحيم على الأرض لتصحيح.
  2. من الصعب التأكد من التخلص.

الآن مع عدم وجود أقفال ، من الواضح أنك لن تصطدم بالكمال.

أكبر صفقة هي ذلك الأقفال لا تتكون.

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

ستصبح هذه المشكلات واضحة لأي شخص يجب أن يبني نظامًا متزامنًا كبيرًا ومعقدًا (وحلها كان دافعًا كبيرًا لـ Hickey الغني في خلق clojure).

القضية الثانية هي أداء.

كل من القفل و STM يفرضون بوضوح النفقات العامة. ولكن في بعض الحالات المهمة ، يمكن أن تكون النفقات العامة STM أقل بكثير.

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

طالما أنك تكتب برامج متسلسلة بدقة (قم ب ، ثم B ، ثم C ؛ الانتهاء!) ليس لديك مشاكل في التزامن ، وتظل آليات التزامن في اللغة غير ذات صلة.

عندما تتخرج من برامج "تمرين البرمجة" إلى الأشياء في العالم الحقيقي ، فإنك تواجه مشكلات في حلها متعدد الخيوط (أو أي نكهة من التزامن لديك).

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

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

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

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

يمكن العثور على مناقشة بداية مفيدة لهذا الموضوع في ويكيبيديا.

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

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

إن التفكير في التداولات بين التزامن القائم على القفل وخالية من القفل يشبه مشكلة المقيِّم المشترك: يمكن للمرء أن ينفذ أقفال من حيث العمليات الذرية (على سبيل المثال مقارنة و SWAP ، أو CAS) ، ويمكن للمرء تنفيذ العمليات الذرية من حيث المصطلحات من الأقفال. أيهما يجب أن يكون في القاع؟

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