কোন পদ্ধতিটি থ্রেড-নিরাপদ করে তোলে? নিয়ম কি?


156

কোন পদ্ধতির থ্রেড-নিরাপদ করে তোলে সেগুলির জন্য কি সামগ্রিক বিধি / নির্দেশিকা রয়েছে? আমি বুঝতে পারি যে সম্ভবত এক মিলিয়ন ওয়ান অফ পরিস্থিতি আছে, তবে সাধারণভাবে কী হবে? এটা কি সহজ?

  1. যদি কোনও পদ্ধতি কেবল স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস করে তবে এটি থ্রেড নিরাপদ।

এইটাই কি সেইটা? এটি কি স্থির পদ্ধতিগুলির জন্যও প্রযোজ্য?

@ সাইবাইসের সরবরাহ করা একটি উত্তর ছিল:

স্থানীয় ভেরিয়েবলগুলি থ্রেডগুলির মধ্যে ভাগ করা যায় না কারণ প্রতিটি থ্রেড নিজস্ব স্ট্যাক পায়।

এটি কি স্থির পদ্ধতিগুলির ক্ষেত্রেও?

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

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

সম্পাদনা এখানে
অনেক ভাল পয়েন্ট তৈরি করা হয়েছে। আমি মনে করি এই প্রশ্নের আসল উত্তর হ'ল: থ্রেড সুরক্ষা নিশ্চিত করার জন্য কোনও সাধারণ নিয়ম নেই " কুল। ফাইন। তবে সাধারণভাবে আমি মনে করি গ্রহণযোগ্য উত্তরটি একটি ভাল, সংক্ষিপ্ত সংক্ষিপ্তসার সরবরাহ করে। সর্বদা ব্যতিক্রম আছে। তাই হোক। আমি এটার সাথে বাঁচতে পারি।


59
আপনাকে কোনও লকেথ ছাড়াই অন্যান্য থ্রেড দ্বারা অ্যাক্সেস করা ভেরিয়েবলগুলি অ্যাক্সেস করতে হবে না।
হ্যানস প্যাস্যান্ট

4
হান্থ পাঠান্ট আইগরে পরিণত হয়েছে!
মার্টিন জেমস

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

আপনাকে ঘূর্ণিঝড়ের মধ্যে নিয়ে যাওয়ার জন্য এখানে এরিকের একটি সুন্দর ব্লগ।
আরবিটি

উত্তর:


139

যদি কোনও পদ্ধতি (উদাহরণ বা স্থিতিশীল) কেবল সেই পদ্ধতির মধ্যে স্কেপড ভেরিয়েবলগুলি উল্লেখ করে তবে এটি থ্রেড নিরাপদ কারণ প্রতিটি থ্রেডের নিজস্ব স্ট্যাক রয়েছে:

এই উদাহরণে, একাধিক থ্রেড ThreadSafeMethodইস্যু ছাড়াই একযোগে কল করতে পারে ।

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number; // each thread will have its own variable for number.
        number = parameter1.Length;
        return number;
    }
}

এটিও সত্য যদি পদ্ধতিটি অন্য শ্রেণির পদ্ধতিতে কল করে যা কেবল স্থানীয়ভাবে স্কোপযুক্ত ভেরিয়েবলগুলি উল্লেখ করে:

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number;
        number = this.GetLength(parameter1);
        return number;
    }

    private int GetLength(string value)
    {
        int length = value.Length;
        return length;
    }
}

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

public class Thing
{
    private string someValue; // all threads will read and write to this same field value

    public int NonThreadSafeMethod(string parameter1)
    {
        this.someValue = parameter1;

        int number;

        // Since access to someValue is not synchronised by the class, a separate thread
        // could have changed its value between this thread setting its value at the start 
        // of the method and this line reading its value.
        number = this.someValue.Length;
        return number;
    }
}

আপনার সচেতন হওয়া উচিত যে পদ্ধতিতে পাস হওয়া কোনও পরামিতি যা কোনও কাঠামো বা অপরিবর্তনীয় নয় পদ্ধতিটির ক্ষেত্রের বাইরে অন্য থ্রেডের মাধ্যমে পরিবর্তিত হতে পারে।

যথাযথ সম্মতি নিশ্চিত করতে আপনাকে লকিং ব্যবহার করতে হবে।

আরও তথ্যের জন্য দেখুন লক স্টেটমেন্ট সি # রেফারেন্স এবং রিডউইটারলকস্লিম দেখুন

লক বেশিরভাগ সময় এক কার্যকারিতা সরবরাহের জন্য কার্যকর,
ReadWriterLockSlimযদি আপনার একাধিক পাঠক এবং একক লেখকের প্রয়োজন হয় useful


15
তৃতীয় উদাহরণে private string someValue;নয় staticতাই প্রতিটি উদাহরণ সেই পরিবর্তনশীলটির একটি পৃথক অনুলিপি পাবে। সুতরাং আপনি দয়া করে ব্যাখ্যা করতে পারেন কীভাবে এটি থ্রেড নিরাপদ নয়?
ভরদ্বাজ

29
@ ভরদ্বাজ যদি Thingএকাধিক থ্রেড দ্বারা অ্যাক্সেস করা শ্রেণীর কোনও উদাহরণ থাকে
ট্রেভর পিলি

111

যদি কোনও পদ্ধতি কেবল স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস করে তবে এটি থ্রেড নিরাপদ। এইটাই কি সেইটা?

নিখুঁতভাবে না। আপনি থ্রেডসেফ নয় এমন একক থ্রেড থেকে অ্যাক্সেস কেবল একক স্থানীয় ভেরিয়েবল সহ একটি প্রোগ্রাম লিখতে পারেন:

https://stackoverflow.com/a/8883117/88656

এটি কি স্থির পদ্ধতিগুলির জন্যও প্রযোজ্য?

একেবারে না.

@ সাইবাইসের সরবরাহ করা একটি উত্তর ছিল: "স্থানীয় ভেরিয়েবলগুলি থ্রেডগুলির মধ্যে ভাগ করা যায় না কারণ প্রতিটি থ্রেড নিজস্ব স্ট্যাক পায়।"

একেবারে না. স্থানীয় ভেরিয়েবলের স্বতন্ত্র বৈশিষ্ট্যটি হ'ল এটি কেবল স্থানীয় ক্ষেত্রের মধ্যে থেকেই দৃশ্যমান , এটি অস্থায়ী পুলের বরাদ্দ নয় । দুটি ভিন্ন থ্রেড থেকে একই স্থানীয় ভেরিয়েবল অ্যাক্সেস করা পুরোপুরি আইনী এবং সম্ভব। আপনি বেনামে পদ্ধতি, ল্যাম্বডাস, পুনরাবৃত্তকারী ব্লক বা অ্যাসিঙ্ক পদ্ধতি ব্যবহার করে এটি করতে পারেন।

এটি কি স্থির পদ্ধতিগুলির ক্ষেত্রেও?

একেবারে না.

যদি কোনও পদ্ধতি একটি রেফারেন্স অবজেক্ট পাস করে তবে থ্রেড সুরক্ষাটি কি ভেঙে দেয়?

হতে পারে.

আমি কিছু গবেষণা করেছি, এবং নির্দিষ্ট কিছু ক্ষেত্রে প্রচুর পরিমাণে আছে, তবে আমি কোনও পদ্ধতিটি থ্রেড নিরাপদ কিনা তা নিশ্চিত করার জন্য অনুসরণ করতে কেবল কয়েকটি নিয়ম, নির্দেশিকা ব্যবহার করে সংজ্ঞা দিতে সক্ষম হবেন আশা করি।

হতাশার সাথে আপনাকে বাঁচতে শিখতে হবে। এটি একটি খুব কঠিন বিষয়।

সুতরাং, আমি অনুমান করি আমার চূড়ান্ত প্রশ্নটি হ'ল: "এমন কোনও নিয়মের একটি সংক্ষিপ্ত তালিকা আছে যা থ্রেড-নিরাপদ পদ্ধতিটি সংজ্ঞায়িত করে?

নাঃ। আপনি যেমন আমার উদাহরণ থেকে দেখেছেন আগে একটি খালি পদ্ধতি নন-থ্রেড-নিরাপদ হতে পারে । আপনি পাশাপাশি জিজ্ঞাসা করতে পারেন "নিয়মের একটি সংক্ষিপ্ত তালিকা রয়েছে যা কোনও পদ্ধতিটি সঠিক তা নিশ্চিত করে "। কোন নেই. থ্রেড সুরক্ষা অত্যন্ত জটিল ধরণের নির্ভুলতা ছাড়া আর কিছুই নয়।

তদতিরিক্ত, আপনি যে প্রশ্নটি জিজ্ঞাসা করছেন তা থ্রেড সুরক্ষা সম্পর্কে আপনার মৌলিক ভুল বোঝাবুঝিকে নির্দেশ করে। থ্রেড সুরক্ষা একটি বিশ্বব্যাপী , কোনও প্রোগ্রামের স্থানীয় সম্পত্তি নয় । এটি অধিকার পেতে এত কঠিন হওয়ার কারণ হ'ল আপনার অবশ্যই পুরো প্রোগ্রামটির থ্রেডিং আচরণ সম্পর্কে একটি সম্পূর্ণ জ্ঞান থাকতে হবে এটির সুরক্ষা নিশ্চিত করার জন্য থাকতে হবে।

আবার আমার উদাহরণটি দেখুন: প্রতিটি পদ্ধতিই তুচ্ছ । পদ্ধতিগুলি একে অপরের সাথে "গ্লোবাল" পর্যায়ে যোগাযোগ করে যা প্রোগ্রামটিকে অচলাবস্থায় পরিণত করে। আপনি প্রতিটি পদ্ধতির দিকে নজর রাখতে পারবেন না এবং এটিকে "নিরাপদ" হিসাবে পরীক্ষা করে দেখতে পারবেন না এবং তারপরে পুরো প্রোগ্রামটি নিরাপদ বলে আপনি আশা করতে পারেন যে আপনার ঘরটি 100% নন-ফাঁকা ইট দিয়ে তৈরি হয়েছে যে ঘরটিও অ ঠালা। বাড়ির খোলামেলা পুরো জিনিসটির একটি বিশ্বব্যাপী সম্পত্তি, এর অংশগুলির সম্পত্তিগুলির সমষ্টি নয়।


14
মূল বিবৃতি: থ্রেড সুরক্ষা একটি বিশ্বব্যাপী, কোনও প্রোগ্রামের স্থানীয় সম্পত্তি নয়।
গ্রেগ ডি

5
@ বিজনহর্ন: class C { public static Func<int> getter; public static Action<int> setter; public static void M() { int x = 0; getter = ()=>x; setter = y=>{x=y;};} } এম () কল করুন, তারপরে দুটি আলাদা থ্রেডে সিজেটার এবং সিসেটর কল করুন। স্থানীয় ভেরিয়েবলটি স্থানীয় হলেও এটি দুটি ভিন্ন থ্রেডে লেখা এবং পড়তে পারে। আবার: স্থানীয় ভেরিয়েবলের সংজ্ঞা বৈশিষ্ট্য হ'ল এটি স্থানীয় , এটি থ্রেডের স্ট্যাকের উপরে নয়
এরিক লিপার্ট

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

7
@ এরিকলিপার্ট: অনেক শ্রেণীর জন্য এমএসডিএন ডকুমেন্টেশন ঘোষণা করে যে 'এই ধরণের সদস্য পাবলিক স্ট্যাটিক (ভিজ্যুয়াল বেসিকের অংশীদারি) সদস্য থ্রেড নিরাপদ। কোনও উদাহরণ সদস্যদের থ্রেড নিরাপদ থাকার গ্যারান্টি নেই '' বা কখনও কখনও 'এই ধরণের থ্রেড নিরাপদ।' (যেমন স্ট্রিং), থ্রেড-সুরক্ষা বিশ্বব্যাপী উদ্বেগের সাথে কীভাবে এই গ্যারান্টি দেওয়া যেতে পারে?
মাইক Zboray

3
@ মিকেজ: ভাল প্রশ্ন হয় এই পদ্ধতিগুলি কোনও রাষ্ট্রকে রূপান্তরিত করে না, বা যখন তারা করে, তখন তারা লক ছাড়াই রাষ্ট্রকে নিরাপদে রূপান্তরিত করে, বা যদি তারা লক ব্যবহার করে, তবে তারা এমনভাবে এমনটি করে যা গ্যারান্টি দেয় যে গ্লোবাল "লক অর্ডার" লঙ্ঘিত হয়নি। স্ট্রিংগুলি অপরিবর্তনীয় ডেটা স্ট্রাকচার যাঁর পদ্ধতিগুলি কোনও কিছুর রূপান্তরিত করে না তাই স্ট্রিংটি সহজেই নিরাপদ করা যায়।
এরিক লিপার্ট

11

কোন ধরাবাঁধা নিয়ম নেই।

.NET এ কোড থ্রেডকে নিরাপদ করার জন্য এখানে কিছু নিয়ম রয়েছে এবং কেন এটি ভাল নিয়ম নয়:

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

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


10
লকগুলি ধীর হওয়া দরকার না। তালা অবিশ্বাস্যভাবে দ্রুত; একটি বিনা প্রতিরোধী লকটি দশ থেকে একশো ন্যানোসেকেন্ডের দৈর্ঘ্যের ক্রম হয় । প্রতিদ্বন্দ্বিতা লকগুলি অবশ্যই নির্বিচারে ধীর হয়; আপনি যদি লক প্রতিযোগিতা করছেন বলে যদি আপনার মন্থর হয়ে থাকে তবে কনটেন্টটি সরিয়ে ফেলার জন্য প্রোগ্রামটি পুনরায় প্রকাশ করুন
এরিক লিপার্ট

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

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