سؤال

هل يمكن لأي شخص أن يعطي رمز عينة قاتل بسيط في C#؟ ويرجى إخبار أبسط طريقة للعثور على ديدان في عينة رمز C#. (قد تكون الأداة التي ستكتشف القفل الميت في رمز العينة المحدد.)

ملاحظة: لدي مقابل 2008

لا يوجد حل صحيح

نصائح أخرى

إحدى الطرق الشائعة هي إذا كان لديك أقفال متداخلة لا يتم الحصول عليها بنفس الترتيب. يمكن أن يحصل الموضوع 1 على قفل A و Thread 2 يمكن أن يحصل على Lock B وسيقومون بالدوقة.

var a = new object();
var b = new object();

lock(a) {
   lock(b) {

   }
}

// other thread
lock (b) { 
  lock(a) {

  }
}

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

انظر مشكلة فيلسوف تناول الطعام

WaitHandle fork = new AutoResetEvent(), knife = new AutoResetEvent();

while(Socrates.IsHungry) {
   fork.WaitOne();
   knife.WaitOne();
   Eat();
   fork.Set();
   knife.Set();
} 

// other thread
while(Descartes.IsHungry) {
   knife.WaitOne();
   fork.WaitOne();
   Eat();
   knife.Set();
   fork.Set();
} 

هذا رمز نموذجي لإنشاء طريق مسدود في رمز C#. الخروج من مقالة MSDN هذه: http://msdn.microsoft.com/en-us/magazine/cc188793.aspx

using System;

using System.Threading;


public class Simple {

    static object A = new object();

    static object B = new object();


    static void MethodA()
    {
        Console.WriteLine("Inside methodA");
        lock (A)
        {
            Console.WriteLine("MethodA: Inside LockA and Trying to enter LockB");
            Thread.Sleep(5000);           
            lock (B)
            {
                Console.WriteLine("MethodA: inside LockA and inside LockB");
                Thread.Sleep(5000);
            }
            Console.WriteLine("MethodA: inside LockA and outside LockB");
        }
        Console.WriteLine("MethodA: outside LockA and outside LockB");
    }

    static void MethodB()
    {
        Console.WriteLine("Inside methodB");
        lock (B)
        {
            Console.WriteLine("methodB: Inside LockB");
            Thread.Sleep(5000);
            lock (A)
            {
                Console.WriteLine("methodB: inside LockB and inside LockA");
                Thread.Sleep(5000);
            }
            Console.WriteLine("methodB: inside LockB and outside LockA");
        }
        Console.WriteLine("methodB: outside LockB and outside LockA");
    }

    public static void Main(String[] args)
    {

        Thread Thread1 = new Thread(MethodA);
        Thread Thread2 = new Thread(MethodB);
        Thread1.Start();
        Thread2.Start();
        Console.WriteLine("enter.....");
        Console.ReadLine();

    }
}

للحصول على رمز عينة Deadlock ، حاول استخدام lock(this) في صفك لمحاكاة سيناريو Deadlock. الدفع هذا المثال.

بعد مقالتين من القراءة الجديرين يكتشفوا الجمود في وقت التشغيل ويناقش طرقًا لتجنبهما.

  1. شاشة Deadlock بقلم ستيفن توب.
  2. توقيت مرة أخرى من قبل إيان غريفيث.

هناك طريقة أخرى لتحقيق طريق مسدود في C#. منذ .NET 2.0 SP1 عدد المواضيع في البركة يقتصر على 250 (من 25 في الإصدار السابق) لكل قلب.

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

يمكنك العثور على مثال وتفسير أكثر دقة هنا:برمجة تجمع الخيوط. deadlocks

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

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