বুল কি সি # তে পরমাণু পড়ুন / লেখুন


84

সি # তে কোনও বুল ফিল্ড পারমাণবিক অ্যাক্সেস করা যায় ? বিশেষত, আমার চারপাশে একটি লক লাগানো দরকার:

class Foo
{
   private bool _bar;

   //... in some function on any thread (or many threads)
   _bar = true;

   //... same for a read
   if (_bar) { ... }
}


4
হ্যাঁ, তবে (সম্ভবত) হ্যাঁও। হ্যাঁ একটি বুল ক্ষেত্র অ্যাক্সেস / সেট করা পারমাণবিক, তবে তবে যদি অপারেশনটি না হয় তবে (নীচে ড্রার হেল্পারের উত্তরটি দেখুন) সুতরাং আপনার এখনও লক লাগতে পারে।
জেপি প্রোগ্রামার

উত্তর:


119

হ্যাঁ.

নিম্নলিখিত ডেটা প্রকারগুলি পড়ুন এবং লেখাগুলি হ'ল পারমাণবিক: বুল, চর, বাইট, এসবিটি, সংক্ষিপ্ত, ushort, uint, int, ভাসা এবং রেফারেন্স প্রকারগুলি।

সি # ল্যাঙ্গুয়েজ স্পেকে যেমন পাওয়া যায় ।

সম্পাদনা করুন: এটি সম্ভবত উদ্বায়ী কীওয়ার্ড বোঝা সার্থক ।


10
পয়েন্টারটি নিজেই এটি পুনরায় অর্পণ করে, এটি পারমাণবিক (যেমন ফু ফুও 1 = foo2;
ব্যবহারকারী 142350

4
@ কনফিগুয়েটর: প্রশ্নটি হ'ল আপনি কী চান। লক-মুক্ত প্রোগ্রামগুলি ভুল পাওয়া সহজ; সুতরাং আপনার যদি সত্যিই এটির প্রয়োজন না হয় তবে একটি সহজ কাঠামো (যেমন টিপিএল) ব্যবহার করা ভাল। 'উদ্বায়ী' অন্য কথায় ভুল নয়, তবে ছদ্মবেশী (যেমন অগ্রাধিকার এড়ানো) কোডের একটি চিহ্ন। ওপি সত্যই সে যা চায় তা বলেননি, আমি কেবল উদ্বিগ্ন উইলি-নিলির পরামর্শ দিতে দ্বিধায় পড়েছি ।
ইমন নের্বোন

4
ওয়াও। এটি একটি বিপজ্জনক শব্দ, কারণ সি ++ লোকের পারমাণবিক অর্থ যে কোনও পাঠ্য রচনাও এর সাথে সম্পর্কিত মেমরি বেড়া দ্বারা ঘিরে রয়েছে। যা অবশ্যই সি # তে কেস নয়। কারণ অন্যথায় সমস্ত ভেরিয়েবলের জন্য বাধ্যতামূলক <লম্বা since সি # পার্লেন্সে এখানে পারমাণবিক অর্থ বোঝানো হয় যখন পড়তে বা লেখার পরিণাম ঘটে তখন এগুলি কখনও ভাঙ্গা অবস্থায় না থাকার গ্যারান্টিযুক্ত । তবে এটি "শেষ অবধি" কখনই রয়েছে তা কিছুই জানায় না।
v.oddou

4
যদি অন্তর্নিহিত এবং দীর্ঘ পর্যন্ত লেখাগুলি পারমাণবিক হয়, তবে Interlocked.Add(ref myInt);উদাহরণস্বরূপ কখন ব্যবহার করবেন ?
মাইক ডি ক্লার্ক

6
@ মাইকেডে ক্লার্ক পড়া এবং লেখাই পারমাণবিক তবে আলাদা। i++সমান i=i+1, এর অর্থ আপনি পারমাণবিক পাঠ করেন, তারপরে সংযোজন করুন, তারপরে পরমাণু লিখুন। আর একটি থ্রেড iপড়ার পরে পরিবর্তিত হতে পারে তবে লেখার আগে। উদাহরণস্বরূপ দুটি থ্রেড i++একই সাথে একই সাথে করা আমি একই সাথে পড়তে (এবং এইভাবে একই মানটি পড়তে) হতে পারি, এটিতে একটি যুক্ত করুন এবং তারপরে উভয়ই একই মান লিখুন, কার্যকরভাবে কেবল একবার যুক্ত করে। ইন্টারলকড dএড এটিকে প্রতিরোধ করে। একটি সাধারণ নিয়ম হিসাবে যে টাইপটি একটি পারমাণবিক তা কেবল তখনই কার্যকর যখন কেবল একটি থ্রেড রচনা থাকলেও অনেকগুলি থ্রেড পড়ে।
জ্যানিস ফ্রয়েস

49

উপরে উল্লিখিত উলটি পারমাণবিক হলেও আপনার এখনও মনে রাখা দরকার যে এটি আপনি এটির সাথে কী করতে চান তার উপরও নির্ভর করে।

if(b == false)
{
    //do something
}

কোনও পারমাণবিক ক্রিয়াকলাপ নয় যার অর্থ, বি স্টেটমেন্টের পরে বর্তমান থ্রেড কোড কার্যকর করার আগে খ মান পরিবর্তন হতে পারে।


30

বুল অ্যাক্সেসগুলি সত্যই পারমাণবিক, তবে এটি পুরো গল্প নয়।

'অসম্পূর্ণভাবে লিখিত' এমন কোনও মূল্য পড়ার জন্য আপনাকে চিন্তার দরকার নেই - এটি কোনও ক্ষেত্রেই বুলের পক্ষে সম্ভবত কী বোঝাতে পারে তা পরিষ্কার নয় - তবে আপনাকে প্রসেসরের ক্যাশের বিষয়ে চিন্তা করতে হবে, কমপক্ষে যদি বিশদ বিবরণ থাকে তবে সময়সীমা একটি বিষয়। থ্রেড # 1 কোর এ চলমান যদি আপনার _barক্যাশে থাকে এবং _barথ্রেড # 2 দ্বারা অন্য কোনও কোরে আপডেট হয়ে যায় তবে থ্রেড # 1 অবিলম্বে পরিবর্তনটি দেখতে পাবে না যদি আপনি লকিং যোগ না _barকরেন volatile, হিসাবে ঘোষণা করেন বা স্পষ্টভাবে কল সন্নিবেশ করান Thread.MemoryBarrier()না ক্যাশেড মান।


4
"এটি স্পষ্ট নয় যে এটি কোনও অবস্থাতেই বুলের পক্ষে কী বোঝাতে পারে" পারমাণবিকতায় মেমরির কেবলমাত্র একটি বাইটে থাকা আইটেমগুলি একই সাথে পুরো বাইটটিতে লিখিত হয় বলে। দ্বিগুণ আইটেম বনাম যা একাধিক বাইটে বিদ্যমান, একটি বাইট অন্য বাইটের আগে লেখা যেতে পারে এবং আপনি অর্ধেক লিখিত মেমরির অবস্থানটি পর্যবেক্ষণ করতে পারেন।
MindStalker

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

4
যদি আপনি কোনও চর্বিযুক্ত বস্তু তৈরি করেন এবং এটিতে একটি রেফারেন্স স্যুইচ করেন যা অন্য থ্রেড থেকে পড়তে পারে তবে একটি মেমরি বাধা কার্যকর। বাধা গ্যারান্টি দেয় যে রেফারেন্সটি ফ্যাট অবজেক্টের বাকি অংশের আগে মুখ্য স্মৃতিতে আপডেট হয় না। অন্যান্য থ্রেডগুলি ফ্যাট অবজেক্টটি মূল স্মৃতিতে আসলে উপলব্ধ হওয়ার আগে রেফারেন্স আপডেটটি কখনও না দেখার গ্যারান্টিযুক্ত। var fatObject = new FatObject(); Thread.MemoryBarrier(); _sharedRefToFat = fatObject;
TiMoch

1

আমি যে পদ্ধতিটি ব্যবহার করেছি, এবং আমি সঠিক বলে মনে করি তা হ'ল

volatile bool b = false;

.. rarely signal an update with a large state change...

lock b_lock
{
  b = true;
  //other;
}

... another thread ...

if(b)
{
    lock b_lock
    {
       if(b)
       {
           //other stuff
           b = false;
       }
     }
}

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


4
এটি সাধারণভাবে লক করার ক্ষেত্রে সত্যই সঠিক পদ্ধতি, তবে যদি বুলস পারমাণবিক হয় তবে লকটি বাদ দেওয়া সহজ (এবং দ্রুত)।
dbkk

4
লক ব্যতীত তখন "বৃহত রাষ্ট্র পরিবর্তন" পারমাণবিকভাবে করা হবে না। লক -> সেট | চেক -> লক -> চেক পদ্ধতির মাধ্যমে "// অন্যান্য জিনিস" কোডের আগে "// অন্যান্য" কোডটি কার্যকর করা হয়েছে তাও নিশ্চিত করবে। "অন্য থ্রেড" বিভাগটি বহুবার পুনরাবৃত্তি হচ্ছে (যা এটি আমার ক্ষেত্রে হয়) ধরে নেওয়া, বেশিরভাগ সময় কেবল একটি
বুল

4
ঠিক আছে lock(), আপনার কাছে থাকলে আপনার দরকার নেই volatile
xmedeko
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.