আমি এটা শুনে const
মানে থ্রেড-নিরাপদ মধ্যে সি ++ 11 । এটা কি সত্যি?
এটা কিছুটা সত্য ...
থ্রেড-সুরক্ষার জন্য স্ট্যান্ডার্ড ল্যাঙ্গুয়েজটি এটাই বলে:
[1.10 / 4]
দুটি এক্সপ্রেশন মূল্যায়নের দ্বন্দ্ব যদি তাদের মধ্যে একটি মেমরি অবস্থান (1.7) পরিবর্তন করে এবং অন্যটি একই মেমরির অবস্থানটিতে অ্যাক্সেস করে বা সংশোধন করে।
[১.১০ / ২১]
কোনও প্রোগ্রামের সম্পাদনটিতে একটি ডেটা রেস থাকে যদি এতে বিভিন্ন থ্রেডে দুটি বিবাদমূলক ক্রিয়া থাকে, যার মধ্যে একটি অন্তত পরমাণু নয় এবং অন্যটির আগেও ঘটে না। এ জাতীয় যে কোনও ডেটা রেসের ফলাফল নির্ধারিত আচরণের ফলাফল।
যা ডেটা রেসের জন্য পর্যাপ্ত শর্ত ছাড়া আর কিছুই নয় :
- প্রদত্ত জিনিসে একই সাথে দুটি বা আরও বেশি ক্রিয়া সম্পাদন করা হচ্ছে; এবং
- তাদের মধ্যে কমপক্ষে একটি লেখা।
স্ট্যান্ডার্ড লাইব্রেরী যে তৈরী করে, একটু যাচ্ছে আরো:
[১ 17..6..5.৯ / ১]
এই বিভাগটি প্রয়োজনীয়তাগুলি নির্দিষ্ট করে যা ডেটা দৌড় প্রতিরোধের জন্য প্রয়োগগুলি পূরণ করতে হবে (১.১০)। প্রতিটি স্ট্যান্ডার্ড গ্রন্থাগার ফাংশন প্রতিটি প্রয়োজন মেটাবে অন্যথায় নির্দিষ্ট না করা পর্যন্ত। বাস্তবায়নগুলি নীচে নির্দিষ্ট করা ব্যতীত অন্যান্য ক্ষেত্রে ডেটা রেসগুলিকে আটকাতে পারে।
[17.6.5.9/3]
একটি C ++ স্ট্যান্ডার্ডের লাইব্রেরি ফাংশন করবে না প্রত্যক্ষ বা পরোক্ষভাবে বস্তু (1.10) বর্তমান থ্রেড যদি না বস্তু ফাংশনের অ- মাধ্যমে প্রত্যক্ষ বা পরোক্ষভাবে ব্যবহার করা হয় আর অন্য থ্রেড দ্বারা অ্যাক্সেসযোগ্য সংশোধন const আর্গুমেন্ট সহthis
।
যা সহজ ভাষায় বলছেন যে এটা আশা উপর অপারেশন const
বস্তু হতে থ্রেড-নিরাপদ । এর অর্থ হ'ল স্ট্যান্ডার্ড লাইব্রেরি যতক্ষণ না const
আপনার নিজের ধরণের অবজেক্টগুলিতে অপারেশন করবে ততক্ষণ কোনও ডেটা রেসের প্রচলন করবে না
- সম্পূর্ণরূপে পড়া নিয়ে গঠিত - এটি কোনও লেখক নেই -; অথবা
- অভ্যন্তরীণভাবে সিনক্রোনাইজ করে।
যদি এই প্রত্যাশাটি আপনার কোনও ধরণের জন্য না ধরে থাকে তবে স্ট্যান্ডার্ড লাইব্রেরির যে কোনও উপাদানটির সাথে প্রত্যক্ষ বা অপ্রত্যক্ষভাবে একসাথে এটি ব্যবহার করার ফলে ডেটা দৌড় হতে পারে । উপসংহারে, const
মানে স্ট্যান্ডার্ড লাইব্রেরি দৃষ্টিকোণ থেকে থ্রেড-নিরাপদ । এটি লক্ষ্য করা গুরুত্বপূর্ণ যে এটি নিছক একটি চুক্তি এবং এটি সংকলক দ্বারা প্রয়োগ করা হবে না, যদি আপনি এটি ভেঙে দেন তবে আপনি সংজ্ঞায়িত আচরণ পান এবং আপনি নিজেরাই। উপস্থিত থাকুক বা না থাকুক কোড জেনারেশনকে প্রভাবিত করবে না - এটি ডেটা রেসের ক্ষেত্রে অন্তত নয় -।const
মানে কি const
এখন সমপরিমাণ জাভা এর synchronized
?
কোন । একেবারেই না...
একটি আয়তক্ষেত্র উপস্থাপন করে নিম্নলিখিত অতিরিক্ত মাত্রায় সরলীকৃত শ্রেণীর বিবেচনা করুন:
class rect {
int width = 0, height = 0;
public:
/*...*/
void set_size( int new_width, int new_height ) {
width = new_width;
height = new_height;
}
int area() const {
return width * height;
}
};
সদস্য ফাংশনের area
হয় থ্রেড-নিরাপদ ; এটির জন্য নয় const
, কারণ এটি সম্পূর্ণরূপে পড়ার ক্রিয়ায় অন্তর্ভুক্ত। এতে কোনও লিখিত জড়িত নেই এবং ডেটা দৌড় প্রতিযোগিতার জন্য জড়িত কমপক্ষে একটি লেখার প্রয়োজন । এর অর্থ হল যে আপনি area
যতটা থ্রেড থেকে কল করতে পারেন এবং আপনি সর্বদা সঠিক ফলাফল পাবেন।
মনে রাখবেন এর অর্থ এই নয় যে rect
এটি থ্রেড-নিরাপদ । প্রকৃতপক্ষে, এটি সহজেই দেখা যায় যে যদি কোনও কল একটি প্রদত্ত area
কলকে একই সাথে set_size
করা হয় rect
, তখন area
কোনও পুরানো প্রস্থ এবং একটি নতুন উচ্চতার উপর ভিত্তি করে তার ফলাফলের গণনা শেষ করতে পারে (বা এমনকি মানযুক্ত মানগুলিতে) ।
কিন্তু যে ঠিক আছে, rect
নয় const
তাই তার এমনকি হতে প্রত্যাশিত থ্রেড-নিরাপদ সব পরে। const rect
অন্যদিকে ঘোষিত একটি বস্তু থ্রেড-নিরাপদ হবে যেহেতু কোনও লেখাই সম্ভব নয় (এবং আপনি যদি const_cast
প্রাথমিকভাবে ঘোষিত কোনও বিষয় বিবেচনা করে থাকেন const
তবে আপনি অপরিবর্তিত আচরণ পাবেন এবং এটি হ'ল )।
তাহলে এর অর্থ কী?
আসুন - ধরে নেওয়া যাক- তর্কের খাতিরে - যে গুণগুলি অপারেশন অত্যন্ত ব্যয়বহুল এবং আমরা যখন সম্ভব হয় তখন আরও ভাল এড়াতে পারি। আমরা যদি কেবল এটির জন্য অনুরোধ করা হয় তবে অঞ্চলটি গণনা করতে পারি, এবং তারপরে ভবিষ্যতে যদি আবার অনুরোধ করা হয় তবে এটি ক্যাশে করতে পারি:
class rect {
int width = 0, height = 0;
mutable int cached_area = 0;
mutable bool cached_area_valid = true;
public:
/*...*/
void set_size( int new_width, int new_height ) {
cached_area_valid = ( width == new_width && height == new_height );
width = new_width;
height = new_height;
}
int area() const {
if( !cached_area_valid ) {
cached_area = width;
cached_area *= height;
cached_area_valid = true;
}
return cached_area;
}
};
[যদি এই উদাহরণটি খুব কৃত্রিম বলে মনে হয় তবে আপনি মানসিকভাবে খুব বড় গতিশীল বরাদ্দকৃত পূর্ণসংখ্যারint
দ্বারা প্রতিস্থাপন করতে পারেন যা সহজাতভাবে অ থ্রেড-নিরাপদ এবং যার জন্য গুণগুলি অত্যন্ত ব্যয়বহুল]
সদস্য ফাংশনের area
নেই থ্রেড-নিরাপদ এটা এখন লিখেছেন করছে এবং অভ্যন্তরীণভাবে সিঙ্ক্রোনাইজ করা হয়। এটা কি কোনো সমস্যা? কলে area
একটি অংশ হিসাবে ঘটতে পারে কপি-কন্সট্রাকটর অন্য বস্তুর, এই ধরনের কন্সট্রাকটর একটি কিছু অপারেশন ডাকা হয়ে থাকতে পারে মান ধারক , এবং যে সময়ে মান গ্রন্থাগার এই অপারেশন হিসেবে আচরণ করে আশা পঠিত বিষয়ে তথ্য ঘোড়দৌড় । তবে আমরা লিখছি!
যত তাড়াতাড়ি আমরা করা rect
একটি মান ধারক --directly বা indirectly-- আমরা ঢুকছে চুক্তি সঙ্গে স্ট্যান্ডার্ড লাইব্রেরী । const
সেই চুক্তিকে সম্মান জানাতে গিয়ে কোনও ফাংশনে লেখার কাজ চালিয়ে যাওয়ার জন্য আমাদের সেই লেখাগুলি অভ্যন্তরীণভাবে সিঙ্ক্রোনাইজ করা দরকার:
class rect {
int width = 0, height = 0;
mutable std::mutex cache_mutex;
mutable int cached_area = 0;
mutable bool cached_area_valid = true;
public:
/*...*/
void set_size( int new_width, int new_height ) {
if( new_width != width || new_height != height )
{
std::lock_guard< std::mutex > guard( cache_mutex );
cached_area_valid = false;
}
width = new_width;
height = new_height;
}
int area() const {
std::lock_guard< std::mutex > guard( cache_mutex );
if( !cached_area_valid ) {
cached_area = width;
cached_area *= height;
cached_area_valid = true;
}
return cached_area;
}
};
মনে রাখবেন যে আমরা area
ফাংশনটি থ্রেড-নিরাপদ করেছি , তবে rect
এখনও থ্রেড-নিরাপদ নেই । একটি কল area
একই সময় একটি কলে এ ঘটছে set_size
এখনও কম্পিউটিং ভুল মান শেষ হতে পারে, এর বরাদ্দকরণ যেহেতু width
এবং height
mutex দ্বারা সুরক্ষিত নয়।
যদি আমরা সত্যিই একটি থ্রেড-নিরাপদ চাই rect
, আমরা অ-থ্রেড-নিরাপদ সুরক্ষার জন্য একটি সিঙ্ক্রোনাইজেশন আদিম ব্যবহার করব rect
।
তারা কীওয়ার্ডের বাইরে চলেছে ?
হ্যা তারা. তারা প্রথম দিন থেকেই কীওয়ার্ডের বাইরে চলেছে।
উত্স : আপনি জানেন না const
এবংmutable
- হার্ব সটার