সবচেয়ে খারাপ (আসলে কাজ করবে না)
অ্যাক্সেস পরিবর্তক পরিবর্তন counter
করতেpublic volatile
অন্যান্য লোকেরা যেমন উল্লেখ করেছে, এটি নিজে থেকে আদৌ নিরাপদ নয়। বিন্দু volatile
একাধিক থ্রেড বহু সিপিইউ চলমান এবং তথ্য এবং পুনরায় অর্ডার নির্দেশাবলী ক্যাশে করবে পারেন।
যদি হয় না হয় volatile
এবং সিপিইউ এ একটি মান বাড়িয়ে দেয়, তবে সিপিইউ বি প্রকৃতপক্ষে কিছু সময়ের পরে সেই বর্ধিত মানটি নাও দেখতে পারে যা সমস্যার কারণ হতে পারে।
যদি এটি হয় তবে এটি volatile
কেবল দুটি সিপিইউ একই সময়ে একই ডেটা দেখতে নিশ্চিত করে। এটি তাদের পড়া এবং লেখার ক্রিয়াকলাপকে আন্তঃবিহিত করা থেকে একেবারেই থামায় না যা আপনি এড়াতে চাইছেন এমন সমস্যা।
দ্বিতীয় সেরা:
lock(this.locker) this.counter++
;
এটি করা নিরাপদ (যদি আপনি lock
অন্য যে কোনও জায়গায় অ্যাক্সেস করেন তবে মনে রাখবেনthis.counter
) এটি সুরক্ষিত অন্য কোনও কোড কার্যকর করতে অন্য কোনও থ্রেডকে বাধা দেয় locker
। লকগুলিও ব্যবহার করে, মাল্টি-সিপিইউ পুনর্নির্মাণ সমস্যাটিকে উপরের মতো প্রতিরোধ করে, যা দুর্দান্ত।
সমস্যাটি হচ্ছে, লক করা ধীর এবং আপনি যদি পুনরায় ব্যবহার করেন locker
অন্য কোনও স্থানে যা সত্যিকারের সাথে সম্পর্কিত না হয় তবে আপনি অকারণে আপনার অন্যান্য থ্রেড অবরুদ্ধ করতে পারেন।
সেরা
Interlocked.Increment(ref this.counter);
এটি নিরাপদ, কারণ এটি কার্যকরভাবে 'এক হিট'-এ পঠন, বৃদ্ধি এবং লিখিত করে যা বাধা দেওয়া যায় না। এ কারণে এটি অন্য কোনও কোডকে প্রভাবিত করবে না এবং অন্য কোথাও লক করার দরকার নেই। এটি খুব দ্রুত (যেমন এমএসডিএন বলেছে, আধুনিক সিপিইউগুলিতে, এটি প্রায়শই আক্ষরিক অর্থেই একক সিপিইউ নির্দেশনা থাকে)।
আমি সম্পূর্ণরূপে নিশ্চিত নই যদিও এটি অন্যান্য সিপিইউগুলিকে পুনঃক্রম করার জিনিসগুলি ঘিরে যদি হয়, বা আপনার যদি বর্ধনের সাথে অস্থির সমন্বয় করতে হয় তবে।
InterlockedNotes:
- জড়িত পদ্ধতিগুলি কোনও সংখ্যা বা সিপিইউতে স্বতন্ত্রভাবে নিরাপদ।
- ইন্টারলকড পদ্ধতিগুলি কার্যকর করার নির্দেশগুলির চারপাশে পুরো বেড়া প্রয়োগ করে, যাতে পুনরায় অর্ডারিং হয় না।
- ইন্টারলকড পদ্ধতিগুলির কোনও অস্থির ক্ষেত্রের অ্যাক্সেসের প্রয়োজন হয় না বা এমনকি সমর্থনও করে না , কারণ প্রদত্ত ক্ষেত্রটিতে অপারেশনগুলির চারপাশে অস্থিরতা অর্ধেক বেড়া স্থাপন করা হয় এবং ইন্টারলকড সম্পূর্ণ বেড়া ব্যবহার করে।
পাদটীকা: অস্থির কি জন্য আসলে ভাল।
যেহেতু volatile
এই জাতীয় মাল্টিথ্রেডিং সমস্যাগুলি প্রতিরোধ করে না, এটি কিসের জন্য? একটি ভাল উদাহরণ বলছে যে আপনার দুটি থ্রেড রয়েছে, একটি যা সর্বদা একটি চলককে লেখেন (বলুনqueueLength
) এবং একটি যা সর্বদা একই চলক থেকে পড়ে reads
যদি queueLength
অস্থির না হয় তবে থ্রেড এ পাঁচ বার লিখতে পারে তবে থ্রেড বি এই লেখাগুলি বিলম্বিত হতে পারে (বা এমনকি সম্ভাব্যভাবে ভুল ক্রমেও) দেখতে পাবে।
একটি সমাধান হ'ল লক করা হবে তবে আপনি এই পরিস্থিতিতে অস্থিরতা ব্যবহার করতে পারেন। এটি নিশ্চিত করে যে থ্রেড বি সর্বদা সর্বশেষতম জিনিসটি দেখবে যা থ্রেড এ লিখেছিল। তবে মনে রাখবেন যে এই যুক্তিটি কেবল তখনই কার্যকর হয় যখন আপনার লেখক যারা কখনও না পড়েন, এবং যে পাঠক কখনও লেখেন না এবং যদি আপনি যে জিনিসটি লিখছেন তা যদি পারমাণবিক মান হয়। আপনি যখনই একটি একক পঠন-সংশোধন-লিখন করেন, আপনাকে ইন্টারলকড অপারেশনে যেতে বা একটি লক ব্যবহার করতে হবে।