.NET- এ ডাবল চেকড লকিংয়ে অস্থির পরিবর্তনকারীগুলির প্রয়োজন


85

একাধিক পাঠ্য বলেছেন যে .NET ফিল্ডটিতে ডাবল-চেকড লকটি প্রয়োগ করার সময় আপনি যে ক্ষেত্রটি লক করছেন তাতে অস্থির পরিবর্তনকারী প্রয়োগ করা উচিত। তবে ঠিক কেন? নিম্নলিখিত উদাহরণ বিবেচনা:

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

"লক (সিঙ্করুট)" প্রয়োজনীয় মেমরির ধারাবাহিকতা কেন সম্পাদন করে না? এটা কি সত্য নয় যে "লক" বিবৃতিটি পড়া এবং লেখা উভয়ই অস্থির এবং তাই প্রয়োজনীয় ধারাবাহিকতা সম্পন্ন হবে?


4
এটি ইতিমধ্যে বহুবার চিবানো হয়েছে। yoda.arachsys.com/csharp/singleton.html
হান্স

4
দুর্ভাগ্যক্রমে এই নিবন্ধে জোন দু'বার 'অস্থির' উল্লেখ করেছে এবং কোনটিই রেফারেন্স সরাসরি তার কোড উদাহরণগুলিকে বোঝায় না।
ড্যান এস্পারজা

উদ্বেগ বোঝার জন্য এই নিবন্ধটি দেখুন: igoro.com/archive/volatile-keyword-in-c-memory-model- বর্ণিত মূলত জেআইটির পক্ষে উদাহরণ পরিবর্তনশীলের জন্য সিপিইউ নিবন্ধ ব্যবহার করা তাত্ত্বিকভাবে সম্ভব - বিশেষত যদি আপনার কোনও প্রয়োজন হয় সেখানে সামান্য অতিরিক্ত কোড। সুতরাং যদি একটি স্টেট স্ট্যামনে দু'বার সম্ভাব্য হয়ে থাকে তবে তা অন্য থ্রেডে পরিবর্তিত হয়ে একই মান ফেরত দিতে পারে could বাস্তবে উত্তরটি খুব জটিল, লক স্টেটমেন্টটি এখানে জিনিসগুলি আরও ভাল করার জন্য দায়বদ্ধ হতে পারে বা নাও হতে পারে (চালিয়ে যাওয়া)
user2685937

(পূর্ববর্তী মন্তব্যটি অব্যাহত দেখুন) - এখানে আমি যা ভাবছি তা সত্যিই ঘটছে - মূলত যে কোনও কোড যা ভেরিয়েবল পড়ার বা সেট করার চেয়ে আরও জটিল কিছু করে তা JIT কে বলতে ট্রিগার করতে পারে, এটি কেবলমাত্র লোড করে মেমরিটিতে সংরক্ষণ করার চেষ্টা করতে ভুলে যান কারণ যদি কোনও ফাংশন জেআইটি বলা হয় তবে প্রতিবার সেখানে সঞ্চিত থাকলে রেজিস্টারটি সংরক্ষণ এবং পুনরায় লোড করার সম্ভাবনা রয়েছে, বরং এটি কেবল প্রতিবার মেমরি থেকে সরাসরি লিখে ও পড়েন। আমি কীভাবে জানতে পারি লকটি বিশেষ কিছু নয়? ইগোরের পূর্ববর্তী মন্তব্যে পোস্ট করা লিঙ্কটি দেখুন (পরবর্তী মন্তব্য অব্যাহত)
ব্যবহারকারী ২685959593737

(উপরের ২ টি মন্তব্য দেখুন) - আমি ইগোরের কোডটি পরীক্ষা করেছি এবং এটি যখন নতুন থ্রেড তৈরি করে তখন আমি তার চারপাশে একটি লক যুক্ত করে দিয়েছিলাম এবং এটি লুপও করেছিলাম। এটি এখনও কোডটি প্রস্থান করতে পারে না কারণ দৃষ্টান্তের ভেরিয়েবলটি লুপের বাইরে তোলা হয়েছিল। লুপটিতে যোগ করার পরে একটি সরল স্থানীয় পরিবর্তনশীল সেটটি এখনও লুপের বাইরে চলকটি উত্তোলন করে - এখন আরও জটিল কিছু যেমন বিবৃতি বা কোনও পদ্ধতি কল বা হ্যাঁ এমনকি কোনও লক কল অপ্টিমাইজেশনকে আটকাতে পারে এবং এইভাবে এটি কাজ করে। সুতরাং যে কোনও জটিল কোডটি প্রায়শই জেআইটিকে অনুকূলকরণের পরিবর্তে সরাসরি পরিবর্তনশীল অ্যাক্সেসকে বাধ্য করে। (পরবর্তী মন্তব্য অব্যাহত)
user2685937

উত্তর:


60

অস্থিরতা অপ্রয়োজনীয়। ভাল ধরণের**

volatileচলকটিতে পঠন এবং লেখার মধ্যে একটি মেমরি বাধা তৈরি করতে ব্যবহৃত হয়।
lockব্যবহার করা হলে, ব্লকের lockঅ্যাক্সেসকে একটি থ্রেডে সীমাবদ্ধ করা ছাড়াও এর ভিতরে থাকা ব্লকের চারপাশে মেমরির বাধা তৈরি করে ।
মেমোরি বাধা এটি তৈরি করে যাতে প্রতিটি থ্রেড চলকটির সর্বাধিক বর্তমান মান পড়ে (কোনও রেজিস্টারে ক্যাশে থাকা স্থানীয় মান নয়) এবং যে সংকলক বিবৃতিগুলি পুনরায় অর্ডার করে না। ব্যবহার volatileকরা অপ্রয়োজনীয় ** কারণ আপনি ইতিমধ্যে একটি লক পেয়েছেন।

জোসেফ আলবাহারী এই জিনিসটিকে আমার চেয়ে আরও ভালভাবে ব্যাখ্যা করে।

এবং সি # তে সিঙ্গেলটন বাস্তবায়নের জন্য জোন স্কিটের গাইড পরীক্ষা করে দেখতে ভুলবেন না


আপডেট :
* volatileভেরিয়েবলটি পড়ার কারণ হতে পারে VolatileReadএবং এস হতে লেখায় VolatileWrite, যা এক্স 86 এবং সিএলআর এক্স x64 এর সাথে প্রয়োগ করা হয় MemoryBarrier। তারা অন্যান্য সিস্টেমে সূক্ষ্ম দানাযুক্ত হতে পারে।

** আমার উত্তরটি কেবলমাত্র সঠিক যদি আপনি x86 এবং x64 প্রসেসরের সিএলআর ব্যবহার করেন। এটি অন্যান্য মেমোরি মডেলগুলিতে সত্য হতে পারে যেমন মনো (এবং অন্যান্য বাস্তবায়ন), Itanium64 এবং ভবিষ্যতের হার্ডওয়্যারগুলির মতো। ডাবল চেক লকিংয়ের জন্য জনের "গেটচস" এ তার নিবন্ধে এটি উল্লেখ করা হয়েছে।

দুর্বল মেমরি মডেলের পরিস্থিতিতে কোডটি সঠিকভাবে কাজ করার জন্য - কোনওটি ভেরিয়েবল হিসাবে চিহ্নিত করা volatile, এটি পড়ার সাথে Thread.VolatileReadবা একটি কল সন্নিবেশ করানো Thread.MemoryBarrierপ্রয়োজন হতে পারে।

আমি যা বুঝি সেগুলি থেকে, সিএলআর (এমনকি আইএ 64৪ তেও), লেখাগুলি কখনই পুনরায় অর্ডার হয় না (লেখাগুলি সর্বদা প্রকাশের শব্দার্থক থাকে)। তবে, আইএ 64৪-তে, পাঠগুলি লেখার আগে আসার জন্য পুনঃক্রম হতে পারে, যদি না সেগুলিকে অস্থির চিহ্নিত করা হয়। দুর্ভাগ্যক্রমে, আমার সাথে খেলতে আইএ 64৪ হার্ডওয়্যারটিতে অ্যাক্সেস নেই, তাই আমি এ সম্পর্কে যা কিছু বলি তা জল্পনা ছিল।

আমি এই নিবন্ধগুলি সহায়কও পেয়েছি:
http://www.codeproject.com/KB/tips/MemoryBarrier.aspx
ভ্যান্স মরিসনের নিবন্ধ (এর সাথে সমস্ত লিঙ্ক, এটি ডাবল
চেকড লকিংয়ের বিষয়ে কথা বলে) ক্রিস ব্রুমের নিবন্ধ (এর সাথে সমস্ত লিঙ্ক ) )
জো ডাফি: ডাবল চেকড লকিংয়ের ভাঙা রূপগুলি

লুইস অ্যাব্রেয়ের সিরিজ মাল্টিথ্রিডিংয়ে ধারণাগুলিরও একটি সুন্দর ওভারভিউ দেয়
http://msmvps.com/blogs/luisabreu/archive/2009/06/29/multithreading-load-and-store-reordering.aspx
http: // msmvps। com / ব্লগস / লুইসাব্রেউ / সংরক্ষণাগার / 2009/07/03 / মাল্টিথ্রেডিং-পরিচয়-মেমরি-fens.aspx


জন স্কিটি আসলে বলেছে যে সঠিক মেমরি বেরিয়ার তৈরি করার জন্য অস্থির পরিবর্তনকারী প্রয়োজন, অন্যদিকে প্রথম লিঙ্ক লেখক বলেছেন যে লক (মনিটর.এন্টার) যথেষ্ট হবে। আসলে কে ঠিক ???
কনস্টান্টিন

@ কনস্টান্টিন দেখে মনে হচ্ছে জোন ইটানিয়াম 64৪ প্রসেসরের মেমরির মডেলটির কথা উল্লেখ করছেন, তাই সেক্ষেত্রে অস্থির ব্যবহার প্রয়োজন হতে পারে। তবে x86 এবং x 64 প্রসেসরের অস্থিরতা অপ্রয়োজনীয়। আমি আরও কিছুটা আপডেট করব
ডান

যদি লকটি প্রকৃতপক্ষে কোনও মেমরির বাধা তৈরি করে এবং মেমরি বারিয়ার যদি নির্দেশ নির্দেশ এবং ক্যাশে উভয়ই অবৈধ করে থাকে তবে তা সমস্ত প্রসেসরের উপর কাজ করা উচিত। যাইহোক এটি এত আশ্চর্যজনক যে এই জাতীয় প্রাথমিক জিনিসটি এত বিভ্রান্তি সৃষ্টি করে ...
কনস্টান্টিন

4
এই উত্তরটি আমার কাছে ভুল দেখাচ্ছে। তাহলে volatileউপর অপ্রয়োজনীয় ছিল কোন প্ল্যাটফর্ম তারপর এটি অর্থ হবে জে আই টি JIT মেমরির লোড নিখুত করতে পারেনি object s1 = syncRoot; object s2 = syncRoot;করার object s1 = syncRoot; object s2 = s1;যে মঞ্চে। এটা আমার কাছে খুব অসম্ভব বলে মনে হচ্ছে।
ব্যবহারকারী541686

4
এমনকি সিএলআর যদি লেখাগুলি পুনরায় অর্ডার না করে (আমি সন্দেহ করি যে এটি সত্য, এটির মাধ্যমে অনেকগুলি খুব ভাল অপ্টিমাইজেশন করা যেতে পারে), তবে আমরা যতক্ষণ না কনস্ট্রাক্টরের কলটি ইনলাইন করতে এবং অবজেক্টটিকে জায়গায় জায়গায় তৈরি করতে পারি ততক্ষণ এটি বগি বানাবে ' (আমরা একটি অর্ধ প্রাথমিক জিনিস দেখতে পেলাম)। অন্তর্নিহিত সিপিইউ ব্যবহার করে যে কোনও মেমরি মডেল স্বাধীন ! এরিক লিপার্টের মতে ইন্টেলের সিএলআর কমপক্ষে কনস্ট্রাক্টরদের পরে একটি ঝিল্লির পরিচয় করিয়ে দেয় যা সেই অপটিমাইজেশনকে অস্বীকার করে, তবে এটি অনুমানের দ্বারা আবশ্যক নয় এবং উদাহরণ হিসাবে আমি এআরএম-তে ঘটতে থাকা একই জিনিসটির উপর নির্ভর করব না ..
ভু

34

volatileমাঠ ছাড়াই এটি বাস্তবায়নের একটি উপায় রয়েছে । আমি এটি ব্যাখ্যা করব ...

আমি মনে করি এটি লকটির অভ্যন্তরে মেমরি অ্যাক্সেসকে পুনরায় সাজানো যা বিপজ্জনক, যেমন আপনি লকের বাইরে সম্পূর্ণরূপে প্রাথমিক সূচনা পেতে পারেন না। এটি এড়াতে আমি এটি করি:

public sealed class Singleton
{
   private static Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         // very fast test, without implicit memory barriers or locks
         if (instance == null)
         {
            lock (syncRoot)
            {
               if (instance == null)
               {
                    var temp = new Singleton();

                    // ensures that the instance is well initialized,
                    // and only then, it assigns the static variable.
                    System.Threading.Thread.MemoryBarrier();
                    instance = temp;
               }
            }
         }

         return instance;
      }
   }
}

কোড বোঝা যাচ্ছে

কল্পনা করুন যে সিঙ্গলটন ক্লাসের কনস্ট্রাক্টরের অভ্যন্তরে কিছু সূচনা কোড রয়েছে। ক্ষেত্রটি নতুন অবজেক্টের ঠিকানার সাথে সেট করার পরে যদি এই নির্দেশাবলী পুনরায় সাজানো হয় তবে আপনার একটি অসম্পূর্ণ উদাহরণ রয়েছে ... কল্পনা করুন যে শ্রেণিটিতে এই কোড রয়েছে:

private int _value;
public int Value { get { return this._value; } }

private Singleton()
{
    this._value = 1;
}

এখন নতুন অপারেটরটি ব্যবহার করে কনস্ট্রাক্টরের কাছে কল কল করুন:

instance = new Singleton();

এটি এই ক্রিয়াকলাপগুলিতে প্রসারিত হতে পারে:

ptr = allocate memory for Singleton;
set ptr._value to 1;
set Singleton.instance to ptr;

যদি আমি এই নির্দেশাবলীর এইরকম পুনঃক্রম করতে পারি তবে:

ptr = allocate memory for Singleton;
set Singleton.instance to ptr;
set ptr._value to 1;

এটা কি কোন পার্থক্য তৈরি করছে? আপনি যদি একক সুতোর কথা ভাবেন নাহ্যাঁ আপনি যদি একাধিক থ্রেডের কথা ভাবেন ... তবে থ্রেডটি বাধা হয়ে গেলে কি হবে set instance to ptr:

ptr = allocate memory for Singleton;
set Singleton.instance to ptr;
-- thread interruped here, this can happen inside a lock --
set ptr._value to 1; -- Singleton.instance is not completelly initialized

মেমরি অ্যাক্সেস পুনরায় ক্রমান্বয়ে অনুমতি না দিয়ে মেমরির বাধা এটাই এড়িয়ে চলে:

ptr = allocate memory for Singleton;
set temp to ptr; // temp is a local variable (that is important)
set ptr._value to 1;
-- memory barrier... cannot reorder writes after this point, or reads before it --
-- Singleton.instance is still null --
set Singleton.instance to temp;

শুভ কোডিং!


4
সিএলআর যদি কোনও বস্তুর আরম্ভের আগে অ্যাক্সেসের অনুমতি দেয় তবে এটি সুরক্ষা গর্ত। এমন কোনও সুবিধাযুক্ত শ্রেণীর কল্পনা করুন যার একমাত্র প্রকাশ্য নির্মাতা "SecureMode = 1" সেট করেন এবং তার উদাহরণ পদ্ধতিগুলি এটি পরীক্ষা করে। আপনি যদি কনস্ট্রাক্টর না চালিয়ে এই দৃষ্টান্তগুলির পদ্ধতিগুলি কল করতে পারেন তবে আপনি সুরক্ষা মডেলটি ভেঙে স্যান্ডবক্সিং লঙ্ঘন করতে পারেন।
মাইকেলজিজি

4
@ মিশেলজিজি: আপনি যে ক্ষেত্রে বর্ণনা করেছেন সে ক্ষেত্রে যদি সেই শ্রেণিটি অ্যাক্সেস করতে একাধিক থ্রেড সমর্থন করে, তবে এটি সমস্যা। যদি কন্সট্রাক্টর কলটি জিটারের সাথে অন্তর্ভুক্ত থাকে, তবে সিপিইউর পক্ষে নির্দেশাবলী পুনরায় অর্ডার করা সম্ভব হয় যাতে সঞ্চিত রেফারেন্সটি পুরোপুরি আরম্ভ না হওয়া উদাহরণকে নির্দেশ করে। এটি কোনও সিএলআর সুরক্ষা সমস্যা নয় কারণ এটি এড়ানো যায় না, এটি ব্যবহার করার জন্য প্রোগ্রামারের দায়িত্ব: আন্তঃবিযুক্ত, মেমরি বাধা, লক এবং / বা উদ্বোধনী ক্ষেত্রগুলি, এই জাতীয় শ্রেণীর নির্মাতার অভ্যন্তরে।
মিগুয়েল অ্যাঞ্জেলো

4
কর্টরের অভ্যন্তরে একটি বাধা এটি ঠিক করে না। সিএলআর যদি সিটিআরটি সম্পূর্ণ হওয়ার আগে এবং নতুন কোনও বরাদ্দকৃত বস্তুর রেফারেন্স বরাদ্দ করে তবে একটি থ্রেড একটি অর্ধ-সূচনাযুক্ত বস্তুর উপর একটি উদাহরণ পদ্ধতি কার্যকর করতে পারে।
মাইকেলজিজি

এটিই "বিকল্প প্যাটার্ন" যা রিশ্যার্পার 2016/2017 সি # তে কোনও ডিসিএলের ক্ষেত্রে পরামর্শ দেয়। OTOH, জাভা করে নিশ্চয়তা ফল newসম্পূর্ণরূপে সক্রিয়া করা হয় ..
user2864740

আমি জানি যে এমএস। নেট বাস্তবায়ন কনস্ট্রাক্টরের শেষে একটি মেমরি বাধা রাখে ... তবে দুঃখের চেয়ে এটি নিরাপদ হতে পারে।
মিগুয়েল অ্যাঞ্জেলো

7

আমি মনে করি না যে কেউ আসলেই প্রশ্নের উত্তর দিয়েছে , তাই আমি এটি দিয়ে চেষ্টা করব।

উদ্বায়ী এবং প্রথমগুলি if (instance == null)"প্রয়োজনীয়" নয়। লকটি এই কোডটি থ্রেড-নিরাপদ করে তুলবে।

সুতরাং প্রশ্নটি: আপনি কেন প্রথম যুক্ত করবেন if (instance == null)?

কারণটি সম্ভবত কোডের লক করা বিভাগটি অকারণে চালানো এড়ানো নয়। আপনি লকের অভ্যন্তরে কোডটি সম্পাদন করার সময়, অন্য কোনও থ্রেড যা সেই কোডটি কার্যকর করতে চেষ্টা করে তা অবরুদ্ধ করা আছে, যা আপনি যদি অনেক থ্রেড থেকে ঘন ঘন সিঙ্গলটন অ্যাক্সেস করার চেষ্টা করেন তবে আপনার প্রোগ্রামটি ধীর করবে। ভাষা / প্ল্যাটফর্মের উপর নির্ভর করে লকটি নিজে থেকে এড়ানো যেতে পারে যা আপনি এড়াতে চান।

সুতরাং আপনার তালার দরকার আছে কিনা তা দেখার জন্য প্রথম নাল চেকটি সত্যই দ্রুত উপায় হিসাবে যুক্ত করা হয়েছে। আপনার যদি সিঙ্গলটন তৈরি করার প্রয়োজন না হয় তবে আপনি লকটি পুরোপুরি এড়াতে পারবেন।

তবে আপনি কোনওভাবে লক না করে রেফারেন্সটি বাতিল কিনা তা পরীক্ষা করতে পারবেন না, কারণ প্রসেসরের ক্যাশে হওয়ার কারণে, অন্য থ্রেড এটি পরিবর্তন করতে পারে এবং আপনি একটি "বাসি" মান পড়বেন যা আপনাকে অকারণে লকটিতে প্রবেশ করতে পরিচালিত করবে। তবে আপনি একটি লক এড়ানোর চেষ্টা করছেন!

সুতরাং আপনি লক ব্যবহারের প্রয়োজন ছাড়াই সর্বশেষ মানটি নিশ্চিত করে তা নিশ্চিত করতে আপনি সিঙ্গলটনকে অস্থির করে তুলছেন।

আপনার এখনও অভ্যন্তরীণ লকটি প্রয়োজন কারণ অস্থির কেবলমাত্র ভেরিয়েবলের একক অ্যাক্সেসের সময় আপনাকে রক্ষা করে - আপনি লকটি ব্যবহার না করে এটিকে নিরাপদে পরীক্ষা করতে এবং সেট করতে পারবেন না।

এখন, এটি কি আসলে কার্যকর?

আচ্ছা আমি বলব "বেশিরভাগ ক্ষেত্রে, না"।

যদি সিঙ্গেলটন.আইন্সটেন্স লকগুলির কারণে অদক্ষতার কারণ হতে পারে, তবে আপনি কেন এত ঘন ঘন এই ফোন করছেন যে এটি একটি উল্লেখযোগ্য সমস্যা হবে ? সিঙ্গলটনের পুরো বক্তব্যটি কেবলমাত্র একটি, তাই আপনার কোডটি একবারে সিঙ্গলটন রেফারেন্সটি পড়তে এবং ক্যাশে করতে পারে।

কেবলমাত্র এই ক্ষেত্রেটিই ভাবতে পারি যেখানে এই ক্যাচিং সম্ভব হবে না যখন আপনার প্রচুর পরিমাণে থ্রেড থাকবে (যেমন প্রতিটি অনুরোধ প্রক্রিয়া করার জন্য একটি নতুন থ্রেড ব্যবহার করে এমন একটি সার্ভার লক্ষ লক্ষ স্বল্প-চলমান থ্রেড তৈরি করতে পারে) যা একবার সিঙ্গলটন.ইনস্ট্যান্স কল করতে হবে)।

সুতরাং আমি সন্দেহ করি যে ডাবল চেকড লক করা এমন একটি প্রক্রিয়া যা খুব নির্দিষ্ট পারফরম্যান্স-সমালোচনামূলক ক্ষেত্রে সত্যিকারের স্থান পায় এবং তারপরে প্রত্যেকে "এটি করার সঠিক উপায় এটি" ব্যান্ডউইগানকে আসলে কী করে তা ভেবে চিন্তিত না করেই তা দৃmb়ভাবে উচ্চারিত হয়েছে। তারা এটির জন্য ব্যবহার করছে সেই ক্ষেত্রে আসলে এটি প্রয়োজনীয় হবে।


6
এটি কোথাও ভুল এবং পয়েন্টটি মিস করার মধ্যে রয়েছে। volatileডাবল-চেকড লকিংয়ে লক শব্দার্থবিজ্ঞানের সাথে কোনও সম্পর্ক নেই, এটি মেমরির মডেল এবং ক্যাশে সুসংবদ্ধতার সাথে সম্পর্কিত। এর উদ্দেশ্য হ'ল এটি নিশ্চিত করা যে কোনও থ্রেড এমন কোনও মান পায় যা এখনও অন্য থ্রেডের মাধ্যমে আরম্ভ করা হয় না, যা ডাবল-চেক লক প্যাটার্ন সহজাতভাবে প্রতিরোধ করে না। জাভাতে আপনার অবশ্যই volatileকীওয়ার্ডটি প্রয়োজন ; ইন। নেট এটি দুর্বল, কারণ এটি ইসিএমএ অনুসারে ভুল তবে ঠিক রানটাইম অনুসারে। যে কোনও উপায়ে, lockঅবশ্যই এটি যত্ন নিবে না
অ্যারোনআউট

হাহ? আমি দেখতে পাচ্ছি না যে আপনার বক্তব্যটি আমি যা বলেছি তার সাথে একমত নয়, না আমিও বলেছি যে কোনওভাবেই লক শব্দার্থবিজ্ঞানের সাথে সম্পর্কিত ola
জেসন উইলিয়ামস

6
আপনার উত্তর, এই থ্রেডের অন্যান্য বেশ কয়েকটি বক্তব্যের মতো, দাবি করেছে যে lockকোডগুলি থ্রেড-নিরাপদ করে। এই অংশটি সত্য, তবে ডাবল-চেক লক প্যাটার্ন এটি অনিরাপদ করতে পারে । আপনি কি অনুপস্থিত মনে হয়। এই উত্তরটি থ্রেড সুরক্ষার সমস্যাগুলির সমাধান না করে ডাবল-চেক লকটির অর্থ এবং উদ্দেশ্য সম্পর্কে বিভ্রান্ত বলে মনে হচ্ছে যা কারণ volatile
অ্যারোনআউট

4
instanceচিহ্নিত করা থাকলে এটি কীভাবে অনিরাপদ তৈরি করতে পারে volatile?
ব্যবহারকারীর নিয়ন্ত্রণ

5

ডাবল চেক লক প্যাটার্ন সহ আপনার অস্থির ব্যবহার করা উচিত।

বেশিরভাগ লোকেরা এই নিবন্ধটি প্রমাণ হিসাবে দেখায় যে আপনার অস্থিরতার দরকার নেই: https://msdn.microsoft.com/en-us/magazine/cc163715.aspx#S10

তবে তারা শেষ পর্যন্ত পড়তে ব্যর্থ হয়েছিল: " সতর্কতার একটি চূড়ান্ত শব্দ - আমি বিদ্যমান প্রসেসরের উপর পর্যবেক্ষণ আচরণ থেকে x86 মেমরি মডেলটিতে অনুমান করছি am সুতরাং লো-লক কৌশলগুলিও ভঙ্গুর কারণ হার্ডওয়্যার এবং সংকলকরা সময়ের সাথে সাথে আরও আক্রমণাত্মক হতে পারে । আপনার কোডে এই ভঙ্গুরতার প্রভাব হ্রাস করার জন্য এখানে কিছু কৌশল রয়েছে First প্রথমত, যখনই সম্ভব হয়, কম-লক কৌশলগুলি এড়িয়ে চলুন ((...) অবশেষে, অন্তর্নিহিত গ্যারান্টিগুলির উপর নির্ভর না করে অস্থির ঘোষণাগুলি ব্যবহার করে দুর্বলতম স্মৃতি মডেলটিকে সম্ভব বলে মনে করুন possible "

আপনার যদি আরও দৃinc় বিশ্বাসের প্রয়োজন হয় তবে ইসিএমএ স্পেসে এই নিবন্ধটি পড়ুন অন্যান্য প্ল্যাটফর্মগুলির জন্য ব্যবহার করা হবে: এমএসডিএন.মাইক্রোসফটকম /en-us/magazine/jj863136.aspx

আপনার যদি এই নতুন আর্টিকেলটি আরও পড়ার দৃ need় বিশ্বাসের প্রয়োজন হয় তবে এটি অপরিবর্তনীয় কাজগুলিকে অস্থিরতা ছাড়াই কাজ করা থেকে বিরত রাখতে পারে: এমএসডিএন.ইমিক্রোসফটিও / ম্যাগাজিন /jj883956.aspx

সংক্ষেপে এটি "মুহুর্তের জন্য" আপনার পক্ষে অস্থির ছাড়াই কাজ করে তবে এটি সঠিক কোডটি লেখার এবং অস্থিরতা বা অস্থিরতা / লেখার পদ্ধতি ব্যবহার করার সুযোগ দেবেন না। নিবন্ধগুলি অন্যথায় করার পরামর্শ দেয় কখনও কখনও জেআইটি / সংকলক অনুকূলিতকরণের কিছু সম্ভাব্য ঝুঁকির কথা বাদ দেয় যা আপনার কোডকে প্রভাবিত করতে পারে, পাশাপাশি আমাদের ভবিষ্যতের অপ্টিমাইজেশানগুলি ঘটতে পারে যা আপনার কোডটি ভেঙে দিতে পারে। গত প্রবন্ধে উল্লিখিত অনুমান হিসাবে ইতিমধ্যে অস্থির ছাড়া কাজ করার পূর্ববর্তী অনুমানগুলি এআরএম ধরে রাখতে পারে না।


4
ভাল উত্তর. এই প্রশ্নের একমাত্র সঠিক উত্তরটি সহজ "না"। এটি অনুসারে গৃহীত উত্তরটি ভুল।
ডেনিস ক্যাসেল

3

আফাইক (এবং - সাবধানতার সাথে এটি গ্রহণ করুন, আমি প্রচুর পরিমাণে সমবর্তী জিনিস করছি না) না। লকটি আপনাকে একাধিক প্রতিযোগী (থ্রেড) এর মধ্যে সিংক্রোনাইজেশন দেয়।

অন্যদিকে অস্থিরতা আপনার মেশিনকে প্রতিবারের মানটি পুনর্বিবেচনা করতে বলে, যাতে আপনি কোনও ক্যাশেড (এবং ভুল) মান না পড়ে।

Http://msdn.microsoft.com/en-us/library/ms998558.aspx দেখুন এবং নীচের উদ্ধৃতিটি নোট করুন:

এছাড়াও, উদাহরণটি ভেরিয়েবল অ্যাক্সেস করার আগে উদাহরণটি ভেরিয়েবলের অ্যাসাইনমেন্টটি সম্পূর্ণ হয় তা নিশ্চিত করতে ভেরিয়েবলটিকে অস্থায়ী হিসাবে ঘোষণা করা হয়।

অস্থির একটি বিবরণ: http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx


4
একটি 'লক' এছাড়াও একটি স্মৃতি বাধা প্রদান করে, যেমন (বা তার চেয়ে ভাল) উদ্বায়ী।
হেন্ক হলটারম্যান

2

আমি মনে করি যে আমি যা খুঁজছিলাম তা খুঁজে পেয়েছি। বিশদটি এই নিবন্ধে রয়েছে - http://msdn.microsoft.com/en-us/magazine/cc163715.aspx#S10

সংক্ষেপে বলতে গেলে - NET অস্থির পরিবর্তনকারীটির এই পরিস্থিতিতে প্রকৃতপক্ষে প্রয়োজন হয় না। তবে দুর্বল মেমরির মডেলগুলিতে অলসভাবে শুরু করা অবজেক্টের কনস্ট্রাক্টরে তৈরি লেখাগুলি ফিল্ডে লেখার পরে বিলম্ব হতে পারে, সুতরাং অন্যান্য থ্রেডগুলি যদি বিবৃতিতে প্রথমে দুর্নীতিযুক্ত অ-নাল উদাহরণ পড়তে পারে।


4
এই নিবন্ধটির একেবারে নীচে মনোযোগ সহকারে পড়ুন, বিশেষত শেষ বাক্যটি লেখক বলেছেন: "সতর্কতার একটি চূড়ান্ত শব্দ - আমি বিদ্যমান প্রসেসরের উপর পর্যবেক্ষণ আচরণ থেকে x86 মেমরির মডেলটিতে কেবল অনুমান করছি Thus সুতরাং লো-লক কৌশলগুলিও ভঙ্গুর কারণ কারণ হার্ডওয়্যার এবং সংকলকরা সময়ের সাথে সাথে আরও আক্রমণাত্মক হয়ে উঠতে পারে your আপনার কোডটিতে এই ভঙ্গুরতার প্রভাব হ্রাস করার জন্য এখানে কিছু কৌশল রইল First প্রথমত, যখনই সম্ভব, লো-লক কৌশলগুলি এড়িয়ে চলুন ((...) অবশেষে, দুর্বলতম মেমরির মডেলটিকে ধরে নেওয়া সম্ভব, অন্তর্নিহিত গ্যারান্টির উপর নির্ভর করার পরিবর্তে অস্থির ঘোষণা ব্যবহার করে ""
ব্যবহারকারী2685937

4
আপনার যদি আরও দৃinc়প্রত্যয় প্রয়োজন হয় তবে ইসিএমএ অনুচ্ছেদে এই নিবন্ধটি অন্য প্ল্যাটফর্মের জন্য ব্যবহার করা হবে: এমএসডিএন.মাইক্রোসফটকম /en-us/magazine/jj863136.aspx আপনার যদি আরও দৃinc় বিশ্বাসের প্রয়োজন হয় তবে এই নতুন নিবন্ধটি পড়তে পারেন যে অপ্টিমাইজেশানগুলি রাখা যেতে পারে এটি এটিকে অস্থিতিশীল ছাড়া কাজ করা থেকে বিরত রাখে: msdn.microsoft.com/en-us/magazine/jj883956.aspx সংক্ষেপে এটি আপনার পক্ষে "মুহুর্তের জন্য অস্থির" ছাড়া কাজ করতে পারে, তবে এটি সঠিক কোড লিখতে এবং ব্যবহার করার সুযোগ না দেয় উদ্বায়ী বা উদ্বায়ী / লেখার পদ্ধতি।
user2685937

1

lockযথেষ্ট। এমএস ল্যাঙ্গুয়েজ স্পেস (3.0.০) নিজেই এই নির্ভুল দৃশ্যের উল্লেখ without8.12-এ করেছে, কোনও উল্লেখ ছাড়াই volatile:

একটি আরও ভাল পদ্ধতির একটি ব্যক্তিগত স্ট্যাটিক অবজেক্ট লক করে স্থিতিশীল ডেটা অ্যাক্সেস সুসংগত করা হয়। উদাহরণ স্বরূপ:

class Cache
{
    private static object synchronizationObject = new object();
    public static void Add(object x) {
        lock (Cache.synchronizationObject) {
          ...
        }
    }
    public static void Remove(object x) {
        lock (Cache.synchronizationObject) {
          ...
        }
    }
}

জন স্কিটি তার নিবন্ধে ( yoda.arachsys.com/csharp/singleton.html ) বলেছেন যে এক্ষেত্রে যথাযথ স্মৃতি প্রতিবন্ধকতার জন্য অস্থির প্রয়োজন। মার্ক, আপনি এই সম্পর্কে মন্তব্য করতে পারেন?
কনস্টান্টিন

আহ, আমি ডাবল-চেক করা লকটি লক্ষ্য করিনি; কেবল: এটি করবেন না ;
মার্ক

আমি প্রকৃতপক্ষে ভাবি যে ডাবল-চেক করা লকটি একটি ভাল কার্য সম্পাদন ভিত্তিক। এছাড়াও যদি ক্ষেত্রটিকে অস্থিতিশীল করে তোলা প্রয়োজন হয়, যখন এটি লকের মধ্যে প্রবেশ করা হয়, তবে ডাবল-চকযুক্ত লকটি অন্য কোনও লকের চেয়ে বেশি খারাপ নয় ...
কনস্ট্যান্টিন

তবে এটি পৃথক শ্রেণীর পদ্ধতির মতোই কী জোন উল্লেখ করেছেন?
মার্ক গ্র্যাভেল

-3

ডাবল চেকড লক সহ অস্থির ব্যবহার সম্পর্কে এটি একটি দুর্দান্ত পোস্ট post

http://tech.puredanger.com/2007/06/15/double-checked-locking/

জাভাতে, যদি উদ্দেশ্যটি কোনও ভেরিয়েবলকে রক্ষা করা হয় তবে এটি যদি অস্থির হিসাবে চিহ্নিত হয় তবে আপনাকে লক করতে হবে না


4
আকর্ষণীয়, তবে অগত্যা খুব সহায়ক নয়। জেভিএমের মেমরি মডেল এবং সিএলআরের স্মৃতি মডেল একই জিনিস নয়।
বি কেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.