কনস্টের অর্থ কি সি ++ 11 এ থ্রেড-সেফ আছে?


115

আমি এটা শুনে constমানে থ্রেড-নিরাপদ মধ্যে সি ++ 11 । এটা কি সত্যি?

মানে কি constএখন সমপরিমাণ জাভা এর synchronized?

তারা কীওয়ার্ডের বাইরে চলেছে ?


1
সি ++ - প্রায়শই জিজ্ঞাসিত প্রশ্ন সাধারণত সি ++ সম্প্রদায় দ্বারা পরিচালিত হয় এবং আপনি দয়া করে আমাদের চ্যাটে মতামত জানতে চাইতে পারেন।
কুকুরছানা

@ ডেড এমএমজি: আমি সি ++ - ফ্যাক্স এবং এর শিষ্টাচার সম্পর্কে অসচেতন ছিলাম, এটি একটি মন্তব্যে প্রস্তাবিত হয়েছিল।
কে-বালো

2
আপনি কোথায় শুনেছেন যে কনস্টের অর্থ থ্রেড-সেফ?
বি বি

2
@Mark বি ঔষধি Sutter এবং বিয়ারনে স্ট্রোভস্ট্রুপের বলছিল এত স্ট্যান্ডার্ড সি ++ ফাউন্ডেশন , উত্তর নীচে লিঙ্কটি দেখুন।
কে-বালো

যারা উল্লেখ্য এখানে আসার: বাস্তব প্রশ্ন নয় const মানে থ্রেড-নিরাপদ। এটি অর্থহীনতা হবে, অন্যথায় এটির অর্থ হ'ল আপনি কেবল এগিয়ে যেতে এবং প্রতিটি থ্রেড-নিরাপদ পদ্ধতি চিহ্নিত করতে সক্ষম হওয়া উচিত const। বরং, আমরা সত্যিই যে প্রশ্নটি জিজ্ঞাসা করছি তা হ'ল const ইমপ্লাইয়েস থ্রেড-নিরাপদ, এবং এই আলোচনাটি এটাই।
ব্যবহারকারী541686

উত্তর:


131

আমি এটা শুনে constমানে থ্রেড-নিরাপদ মধ্যে সি ++ 11 । এটা কি সত্যি?

এটা কিছুটা সত্য ...

থ্রেড-সুরক্ষার জন্য স্ট্যান্ডার্ড ল্যাঙ্গুয়েজটি এটাই বলে:

[1.10 / 4] দুটি এক্সপ্রেশন মূল্যায়নের দ্বন্দ্ব যদি তাদের মধ্যে একটি মেমরি অবস্থান (1.7) পরিবর্তন করে এবং অন্যটি একই মেমরির অবস্থানটিতে অ্যাক্সেস করে বা সংশোধন করে।

[১.১০ / ২১] কোনও প্রোগ্রামের সম্পাদনটিতে একটি ডেটা রেস থাকে যদি এতে বিভিন্ন থ্রেডে দুটি বিবাদমূলক ক্রিয়া থাকে, যার মধ্যে একটি অন্তত পরমাণু নয় এবং অন্যটির আগেও ঘটে না। এ জাতীয় যে কোনও ডেটা রেসের ফলাফল নির্ধারিত আচরণের ফলাফল।

যা ডেটা রেসের জন্য পর্যাপ্ত শর্ত ছাড়া আর কিছুই নয় :

  1. প্রদত্ত জিনিসে একই সাথে দুটি বা আরও বেশি ক্রিয়া সম্পাদন করা হচ্ছে; এবং
  2. তাদের মধ্যে কমপক্ষে একটি লেখা।

স্ট্যান্ডার্ড লাইব্রেরী যে তৈরী করে, একটু যাচ্ছে আরো:

[১ 17..6..5.৯ / ১] এই বিভাগটি প্রয়োজনীয়তাগুলি নির্দিষ্ট করে যা ডেটা দৌড় প্রতিরোধের জন্য প্রয়োগগুলি পূরণ করতে হবে (১.১০)। প্রতিটি স্ট্যান্ডার্ড গ্রন্থাগার ফাংশন প্রতিটি প্রয়োজন মেটাবে অন্যথায় নির্দিষ্ট না করা পর্যন্ত। বাস্তবায়নগুলি নীচে নির্দিষ্ট করা ব্যতীত অন্যান্য ক্ষেত্রে ডেটা রেসগুলিকে আটকাতে পারে।

[17.6.5.9/3] একটি C ++ স্ট্যান্ডার্ডের লাইব্রেরি ফাংশন করবে না প্রত্যক্ষ বা পরোক্ষভাবে বস্তু (1.10) বর্তমান থ্রেড যদি না বস্তু ফাংশনের অ- মাধ্যমে প্রত্যক্ষ বা পরোক্ষভাবে ব্যবহার করা হয় আর অন্য থ্রেড দ্বারা অ্যাক্সেসযোগ্য সংশোধন const আর্গুমেন্ট সহthis

যা সহজ ভাষায় বলছেন যে এটা আশা উপর অপারেশন constবস্তু হতে থ্রেড-নিরাপদ । এর অর্থ হ'ল স্ট্যান্ডার্ড লাইব্রেরি যতক্ষণ না constআপনার নিজের ধরণের অবজেক্টগুলিতে অপারেশন করবে ততক্ষণ কোনও ডেটা রেসের প্রচলন করবে না

  1. সম্পূর্ণরূপে পড়া নিয়ে গঠিত - এটি কোনও লেখক নেই -; অথবা
  2. অভ্যন্তরীণভাবে সিনক্রোনাইজ করে।

যদি এই প্রত্যাশাটি আপনার কোনও ধরণের জন্য না ধরে থাকে তবে স্ট্যান্ডার্ড লাইব্রেরির যে কোনও উপাদানটির সাথে প্রত্যক্ষ বা অপ্রত্যক্ষভাবে একসাথে এটি ব্যবহার করার ফলে ডেটা দৌড় হতে পারে । উপসংহারে, 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এবং heightmutex দ্বারা সুরক্ষিত নয়।

যদি আমরা সত্যিই একটি থ্রেড-নিরাপদ চাই rect , আমরা অ-থ্রেড-নিরাপদ সুরক্ষার জন্য একটি সিঙ্ক্রোনাইজেশন আদিম ব্যবহার করব rect

তারা কীওয়ার্ডের বাইরে চলেছে ?

হ্যা তারা. তারা প্রথম দিন থেকেই কীওয়ার্ডের বাইরে চলেছে।


উত্স : আপনি জানেন না constএবংmutable - হার্ব সটার


6
@ বেন ভয়েগ্ট: এটি আমার বোঝার জন্য যে সি ++ 11 স্পেসিফিকেশনটি std::stringএমনভাবে শব্দযুক্ত যা ইতিমধ্যে COW নিষিদ্ধ করে । আমি স্পেসিফিকসগুলি মনে রাখছি না, যদিও ...
কে-ব্যালো

3
@ বেনভয়েগ: না। এটি কেবল এই জাতীয় জিনিসগুলিকে অযৌক্তিকভাবে আটকাতে বাধা দেবে- যেমন থ্রেড নিরাপদ নয়। সি ++ 11 ইতিমধ্যে সুস্পষ্টভাবে COW- কে নিষিদ্ধ করেছে- যদিও এই বিশেষ উত্তরণটির সাথে কিছুই করার নেই, এবং এটি COW নিষিদ্ধ করবে না।
কুকুরছানা

2
এটি আমার কাছে মনে হয় একটি যৌক্তিক ফাঁক আছে। [17.6.5.9/3] "এটি প্রত্যক্ষ বা অপ্রত্যক্ষভাবে সংশোধন করবে না" বলে "খুব বেশি" নিষেধ করেছে; এটিতে বলা উচিত "প্রত্যক্ষ বা অপ্রত্যক্ষভাবে কোনও উপাত্তের রেস পরিচয় করিয়ে দেবে না", যদি না পারমাণবিক রচনাটি কোথাও "পরিবর্তন" হিসাবে সংজ্ঞায়িত না হয়। তবে আমি এটি কোথাও খুঁজে পাচ্ছি না।
অ্যান্ডি প্রোল

1
আমি সম্ভবত আমার পুরো বিষয়টি এখানে কিছুটা পরিষ্কার করে দিয়েছি : isocpp.org/blog/2012/12/… যাইহোক সাহায্য করার চেষ্টা করার জন্য আপনাকে ধন্যবাদ।
অ্যান্ডি প্রোল

1
কখনও কখনও আমি আশ্চর্য হয়েছি যে এর মধ্যে কিছু স্ট্যান্ডার্ড অনুচ্ছেদ লিখে দেওয়ার জন্য কে ছিলেন (বা সরাসরি জড়িত ছিলেন) আসলে দায়ী responsible
গোলমরিচ_চিকো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.