ما هو adadlock
دعونا أولاً نلقي نظرة على مثل هذا المثال الحياة: يوجد جسر على النهر ، مع سطح جسر ضيق يمكن أن يستوعب سيارة واحدة فقط ولا يمكنه السماح سيارتين بالانتقال بالتوازي. إذا كانت سيارتان A و B يقودان إلى الجسر من كلا طرفي الجسر ، ثم للسيارة A ، فإنها تسير عبر مقطع من الطريق على الجانب الأيسر من سطح الجسر (أي أنها تشغل جزءًا من موارد الجسر). إذا كنت ترغب في عبور الجسر ، فيجب عليك الانتظار حتى تتخلى Car B عن سطح الجسر على اليمين. السيارة A لا يمكن المضي قدمًا في هذا الوقت ؛ بالنسبة للسيارة B ، فإنه يسير عبر قسم من الطريق على الجانب الأيمن من سطح الجسر (أي أنه يشغل جزءًا من موارد الجسر). إذا كنت ترغب في عبور الجسر ، فيجب عليك الانتظار حتى تتخلى السيارة عن سطح الجسر على اليسار ، ولا يمكن للسيارة B المضي قدمًا في هذا الوقت. لم تنعكس السيارات على كلا الجانبين ، مما أدى إلى انتظار بعضها البعض للتخلي عن سطح الجسر ، لكن لا أحد يفسح المجال وسينتظر إلى ما لا نهاية. هذه الظاهرة هي طريق مسدود. إذا تمت مقارنة السيارة بعملية واستخدمت سطح الجسر كمورد ، فسيتم وصف المشكلة أعلاه على أنها: العملية A تمتلك مورد R1 ، في انتظار الموارد التي تشغلها العملية B ؛ تمتلك العملية B المورد RR ، في انتظار الموارد R1 التي تشغلها عملية A. علاوة على ذلك ، يسمح الموارد R1 و RR فقط بعملية واحدة أن تشغلها ، أي أنه لا يُسمح لعمليتين بالشغل في نفس الوقت. نتيجة لذلك ، لا يمكن للعملية الاستمرار في التنفيذ. إذا لم يتم اتخاذ أي تدابير أخرى ، فسيستمر وضع انتظار الدورة هذا إلى أجل غير مسمى ، وسيحدث مسدود.
في أنظمة الكمبيوتر ، قد تكون موارد البرمجيات والأجهزة مسدودًا. على سبيل المثال: لا يوجد سوى سائق واحد من CD-ROM وطابعة واحدة في النظام. تمتلك عملية واحدة برنامج تشغيل CD-ROM وتتقدم للحصول على طابعة ؛ تمتلك العملية الأخرى الطابعة وتطبق على قرص مضغوط. نتيجة لذلك ، يتم حظر كلتا العمليتين ولا يمكن فصلهما أبدًا بمفردهما.
يشير ما يسمى بالموت إلى موقف يدور فيه عمليات متعددة من خلال الموارد التي يشغلونها وتبقى في طريق مسدود إلى أجل غير مسمى. من الواضح ، إذا لم تكن هناك قوة خارجية ، فسيتم دائمًا حظر جميع العمليات التي تنطوي عليها Deadlock. من المثال أعلاه ، يمكننا أن نرى أن السبب الأساسي للتمثيل المسدود في أنظمة الكمبيوتر هو موارد محدودة وتشغيل غير لائق. وهذا هو: أحد الأسباب هو أن النظام يوفر موارد قليلة للغاية وهو بعيد عن تلبية متطلبات الموارد للعمليات المتزامنة. هذا الجمود الناجم عن الموارد المتنافسة هو جوهر مناقشتنا. على سبيل المثال: الرسالة مورد مؤقت. في مرحلة ما ، تنتظر العملية A رسالة تم إرسالها بواسطة العملية B ، والعملية B تنتظر رسالة تم إرسالها بواسطة العملية C ، والعملية C تنتظر رسالة تم إرسالها بواسطة العملية A. إذا لم تصل الرسالة ، فلن تتمكن أي من العمليات الثلاث A و B و C من المضي قدمًا ، ولن تحدث عمليات Deadlocks أيضًا في مجال الاتصالات. سبب آخر هو حالات الجمود التي تسببها أمر التقدم غير المناسب للعملية. الموارد الصغيرة قد لا تؤدي بالضرورة إلى مصلتة. تمامًا مثل شخصين يعبران جسرًا واحدًا ، إذا كان على كلاهما أن يمر أولاً ويكونا الجمود على الجسر المفرد ، فإنهما سيؤدي حتما إلى طريق مسدود لموارد المنافسة ؛ ومع ذلك ، إذا تحقق شخصان أولاً ما إذا كان هناك أشخاص آخرون على الجسر قبل الذهاب إلى الجسر ، وتصعد فقط الجسر بأنفسهم عندما لا يكون هناك أشخاص آخرون على الجسر ، فسيتم حل المشكلة. لذلك ، إذا تم تصميم البرنامج بشكل غير معقول وتم الترويج للعملية بشكل غير لائق ، فسيؤدي ذلك أيضًا إلى تسبب في مسدود.
طريق مسدود
فقط عندما يحتل موضوع T1 O1 ويتطلب أيضًا O2 ، ويأخذ T2 O2 في هذا الوقت ويتطلب أيضًا O1 سيكون هناك طريق مسدود. (على غرار شخصين يأكلان مع اثنين من عيدان تناول الطعام ، كلاهما يحتاجان إلى خمص واحد من الطرف الآخر لتناول الطعام)
الكود التالي: يحتل مؤشر ترابط T1 O1 ويصدر O1 فقط بعد الحصول على كائن O2. يحتل موضوع T2 O2 أولاً ثم يكتسب O1. في هذا الوقت ، يتم احتلال O1 بواسطة موضوع T1 ، ويشغل O2 بواسطة خيط T2 ، وينتظر T1 و T2 بلا حدود ، وسيحدث Deadlock.
حزمة javasimple ؛/** * Deadlock Demo * author hokui * */فئة عامة diesynchronized {public static void main (string [] args) {/** * إنشاء وبدء ترابط t1 و t2. يجب أن يشارك كلا الموضوعين كائنين O1 و O2*/ Object O1 = كائن جديد () ؛ كائن O2 = كائن جديد () ؛ الموضوع T1 = مؤشر ترابط جديد (جديد T1 (O1 ، O2)) ؛ الموضوع T2 = مؤشر ترابط جديد (جديد T2 (O1 ، O2)) ؛ t1.start () ؛ t2.start () ؛ }} // إنشاء فئتين من مؤشرات الترابط T1 قم بتنفيذ Runnable {Object O1 ؛ كائن O2 ؛ Public T1 (Object O1 ، Object O2) {this.o1 = O1 ؛ this.o2 = O2 ؛ } public void run () {// locks O1 و O2 Synchronized (O1) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } Synchronized (O2) {system.out.println ("O2") ؛ }}}}}}} Class T2 تنفذ Runnable {Object O1 ؛ كائن O2 ؛ Public T2 (Object O1 ، Object O2) {this.o1 = O1 ؛ this.o2 = O2 ؛ } public void run () {synchronized (o2) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {// todo catch catch e.printstacktrace () ؛ } Synchronized (O1) {system.out.println ("O1") ؛ }}}} ملاحظة: يحدث التزامن فقط عند مشاركة O1 و O2. يمكن مشاركة كائنين من خلال المُنشئين.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.