C #: دھاگے سے محفوظ اور جوہری میں کیا فرق ہے؟


جواب 1:

جب متعدد تھریڈز تک رسائی حاصل کی جاتی ہے تو تھریڈ سیف اسباب میں خلل نہیں پڑتا ہے۔ جوہری کا مطلب ناقابل تقسیم ہے ، اس تناظر میں بلاتعطل کے برابر ہے۔

تالے پر عمل درآمد کرنے کے لئے ، آپ کے پاس دو انتخاب ہیں:

  1. ایٹمی کارروائیوں کے لئے ہارڈویئر سپورٹ حاصل کریں - خصوصی جامع ہدایات جو پوری طرح چلتی ہیں ، جیسے ٹیسٹ اور سیٹ۔ ہوشیار رہو (اور اس کا خمیازہ بھگتنا پڑے گا) - پیٹرسن کا الگورتھم۔

تفصیلات میں اپنی مثال کے طور پر ، دونوں غیر محفوظ ہیں۔ اگر میں صحیح طور پر سمجھتا ہوں تو ، آپ کا مطلب کچھ اس طرح ہے:

عوامی کلاس غیر محفوظ
{
    نجی اعتراض ulock = نیا اعتراض ()؛

    عوامی INT غیر محفوظ 1 {حاصل؛ سیٹ؛ ؛ = 0؛

    نجی INT _unsafe2 = 0؛
    عوامی INT غیر محفوظ 2
    {
        حاصل
        {
            لاک (لاک)
            {
                واپسی _unsafe2؛
            }
        }

        سیٹ کریں
        {
            لاک (لاک)
            {
                _unsafe2 = قدر؛
            }
        }
    }
}

ٹیسٹ کوڈ:

var u = نیا غیر محفوظ ()؛

متوازی ۔فورڈ (0 ، 10000000 ، _ =>. u.Unsafe1 ++؛})؛
متوازی ۔فورڈ (0 ، 10000000 ، _ =>. u.Unsafe2 ++؛})؛

کنسول.وائٹ لائن

نتیجہ (ممکنہ بہت سے لوگوں میں سے ایک):

4648265 - 4149827

دونوں کے لئے ، نصف سے زیادہ تازہ کارییں غائب ہوگئیں۔

وجہ یہ ہے کہ ++ جوہری نہیں ہے - یہ درحقیقت تین الگ عمل ہیں:

  1. ویلیو حاصل کریں۔ ویلیو میں 1 شامل کریں۔ سیٹ ویلیو۔

ہم انکریمنٹ آپریشن فراہم کرکے اسے ٹھیک کرسکتے ہیں - جو کرنے کے بہت سے طریقے ہیں ، لیکن یہاں دو ہیں:

عوامی کلاس سیف
{
    نجی آبجیکٹ سلاک = نیا اعتراض ()؛

    پبلک INT Safe1 {get؛ سیٹ؛ }
    عوامی باطل SafeIncrement1 ()
    {
        لاک (لاک)
        {
            this.Safe1 ++؛
        }
    }

    نجی INT _safe2 = 0؛
    عوامی INT سیف 2
    {
        حاصل
        {
            واپسی _ محفوظ 2؛
        }
        سیٹ کریں
        {
            _صفا 2 = قیمت؛
        }
    }
    عوامی باطل SafeIncrement2 ()
    {
        انٹر لاک۔ انٹریمنٹ (ریف _ سیف 2)؛
    }
}

ٹیسٹ کوڈ:

var s = نیا سیف ()؛

متوازی.فورف (0 ، 10000000 ، _ => {s.SafeIncrement1 ()؛})؛
متوازی ۔فورڈ (0 ، 10000000 ، _ => {s.SafeIncrement2 ()؛})؛

کنسول.وائٹ لائن

نتائج دونوں ہی معاملات میں درست ہیں۔ پہلا صرف مجموعی ++ آپریشن کے ارد گرد ایک تالا لگا دیتا ہے ، جبکہ دوسرا ایٹم آپریشنز کے لئے ہارڈ ویئر سپورٹ کا استعمال کرتا ہے۔

مندرجہ بالا دوسرا حامل نوٹ کریں ، جس میں انٹرلاک ہوا ہے۔ اعتراف بہت تیز ہے ، لیکن حقیقت میں نچلی سطح پر ہے اور اس میں محدود ہے کہ وہ باکس سے باہر کیا کرسکتا ہے۔ تاہم ، انٹر لاک پیکیج میں ہونے والی کارروائیوں کو عملی جامہ پہنانے کے لئے استعمال کیا جاسکتا ہے۔

  1. واقف تالے - "مایوس کن سمجھوتہ" کہا جاتا ہے کیونکہ وہ فرض کرتے ہیں کہ آپریشن میں خلل پڑ جائے گا ، لہذا جب تک کہ وہ مشترکہ وسائل حاصل نہ کر لیں شروع کرنے کی زحمت نہ کریں۔ "لاک فری کوڈ" ، a.k.a. موازنہ اور تبدیل کرنے کے ل you ، آپ ایک خاص "کینری" قدر استعمال کرتے ہیں جو آپ شروع میں ہی ریکارڈ کرتے ہیں ، پھر یقینی بنائیں کہ آخر آپ کے تحت کوئی تبدیلی نہیں آئی ہے۔ خیال یہ ہے کہ اگر کوئی دوسرا دھاگہ بھی ساتھ آجاتا ہے تو ، یہ کینری کو مار ڈالے گا ، لہذا آپ شروع سے ہی اپنے لین دین کی دوبارہ کوشش کرنا جانتے ہیں۔ اس کے ل your آپ کے اپنے کوڈ کو بھی جوہری ہونا ضروری ہے۔ - آپ مشترکہ ریاست کو انٹرمیڈیٹ نتائج نہیں لکھ سکتے ، آپ کو یا تو مکمل طور پر کامیاب ہونا پڑے گا یا مکمل طور پر ناکام ہونا پڑے گا (گویا آپ نے کوئی کام انجام نہیں دیا ہے)۔

جواب 2:

دو بالکل مختلف چیزیں۔ تھریڈ سیف کا مطلب ہے کسی فنکشن کو اس طرح لکھا گیا کہ اس کو کئی مختلف دھاگوں کے ذریعہ بار بار کہا جاسکتا ہے ، بغیر ہر تھریڈ کسی دوسرے دھاگے کے عمل میں خلل ڈالتا ہے (مثال کے طور پر ، اگر کسی تغیر کو تبدیل کیا جاتا ہے کہ کوئی دوسرا تھریڈ استعمال کررہا ہے)

جوہری ذرائع (اگر میں وہاں جاؤں جہاں آپ اس کے ساتھ جارہے ہو) کسی شے کی ایک مثال کی تخلیق- لہذا اس سے قطع نظر کہ اس کا ذکر کتنی بار کیا جاتا ہے ، آپ ہمیشہ ایک مثال دیکھتے ہیں (کسی دھاگے سے)


جواب 3:

جوہری آپریشنز تھریڈ سیفٹی کو حاصل کرنے کا ایک ذریعہ ہے یا تو کسی قسم کے تالے جیسے میٹیکس یا سیمفورس کا استعمال کرکے جو داخلی طور پر جوہری کارروائیوں کا استعمال کرتے ہیں یا پھر ایٹمکس اور میموری باڑ کا استعمال کرتے ہوئے لاک فری سنکرونائزیشن کو لاگو کرتے ہیں۔

لہذا قدیم اعداد و شمار کی اقسام پر جوہری کارروائی تھریڈ کی حفاظت کو حاصل کرنے کا ایک ذریعہ ہے لیکن دھاگے کی حفاظت کو خود بخود یقینی نہیں بناتے کیونکہ آپ عام طور پر متعدد آپریشن کرتے ہیں جو ایک دوسرے پر بھروسہ کرتے ہیں۔ آپ کو یہ یقینی بنانا ہوگا کہ یہ آپریشن بغیر کسی مداخلت کے انجام پائے ہیں مثلا. خاموشی کا استعمال۔

ہاں ، ان # جوہری ڈیٹا کی اقسام میں سے کسی کو c # میں لکھنا دھاگے سے محفوظ ہے ، لیکن اس سے آپ تھریڈ میں استعمال ہونے والی تقریب کو محفوظ نہیں بناتے ہیں۔ یہ صرف اس بات کو یقینی بناتا ہے کہ واحد تحریری صحیح طور پر عمل میں لایا جائے یہاں تک کہ اگر دوسرا دھاگہ "اسی وقت" تک رسائی حاصل کرتا ہے۔ کبھی بھی کم نہیں ، موجودہ تھریڈ سے اگلی پڑھی گئی بات کو یقینی نہیں بنایا گیا ہے کہ اس سے پہلے کسی مختلف تھریڈ کے لکھے ہوئے اس قدر کو حاصل کیا جا. جس کی وجہ سے پڑھی گئی قدر درست ہے۔