সি #: থ্রেড-সেফ এবং পারমাণবিকের মধ্যে পার্থক্য কী?


উত্তর 1:

একাধিক থ্রেড থেকে অ্যাক্সেস পাওয়া গেলে থ্রেড-সেফ মানে গুলিয়ে যায় না; পারমাণবিক অর্থ অবিভাজ্য, সেই প্রসঙ্গে নিরবচ্ছিন্ন সমতুল্য।

লকগুলি প্রয়োগ করতে, আপনার দুটি পছন্দ আছে:

  1. পারমাণবিক ক্রিয়াকলাপের জন্য হার্ডওয়্যার সমর্থন রয়েছে - বিশেষত সম্মিলিত নির্দেশাবলী যা পুরোপুরি কার্যকর করে, যেমন টেস্ট- And-set. স্মার্ট থাকুন (এবং এর পরিণতিগুলি ভোগ করুন) - পিটারসনের অ্যালগরিদম।

বিশদগুলিতে আপনার উদাহরণে, উভয়ই অনিরাপদ; যদি আমি সঠিকভাবে বুঝতে পারি তবে আপনি এরকম কিছু বোঝাতে চাইছেন:

পাবলিক ক্লাস অনিরাপদ
{
    প্রাইভেট অবজেক্ট ইউলক = নতুন অবজেক্ট ();

    পাবলিক ইন আনসফ্যাক 1 {পেতে; সেট; ; = 0;

    বেসরকারী int _unsafe2 = 0;
    পাবলিক ইন্ট আনসেফ 2
    {
        পাওয়া
        {
            লক (লক)
            {
                ফিরে আসুন
            }
        }

        সেট
        {
            লক (লক)
            {
                _unsafe2 = মান;
            }
        }
    }
}

পরীক্ষার কোড:

var u = নতুন অনিরাপদ ();

সমান্তরাল.ফর (0, 10000000, _ =>। U.Unsafe1 ++;;);
সমান্তরাল.ফর (0, 10000000, _ => {u.Unsafe2 ++;;);

কনসোল.উরাইটলাইন (স্ট্রিং.ফর্ম্যাট ("{0} - {1}", ইউ.উনসেফ 1, ইউ.উনসেফ 2));

ফলাফল (সম্ভাব্য অনেকের মধ্যে একটি):

4648265 - 4149827

উভয়ের জন্যই অর্ধেকেরও বেশি আপডেট অদৃশ্য হয়ে গেছে।

কারণটি হ'ল ++ পারমাণবিক নয় - এটি আসলে তিনটি পৃথক অপারেশন:

  1. মানটি পান value মূল্যতে 1 যুক্ত করুন et মূল্য সেট করুন।

আমরা এটি পারমাণবিক ইনক্রিমেন্ট অপারেশন সরবরাহ করে এটি ঠিক করতে পারি - এটি করার অনেক উপায় আছে তবে এখানে দুটি রয়েছে:

পাবলিক ক্লাস নিরাপদ
{
    প্রাইভেট অবজেক্ট স্লক = নতুন অবজেক্ট ();

    পাবলিক ইন নিরাপদ 1 {পেতে; সেট; }
    পাবলিক অকার্যকর SafeIncrement1 ()
    {
        লক (লক)
        {
            this.Safe1 ++,;
        }
    }

    প্রাইভেট ইন্ট _সেক 2 = 0;
    পাবলিক ইন নিরাপদ 2
    {
        পাওয়া
        {
            প্রত্যাবর্তন _safe2;
        }
        সেট
        {
            _ এসএফ 2 = মান;
        }
    }
    পাবলিক অকার্যকর SafeIncrement2 ()
    {
        ইন্টারলকড.ইনক্রিমেন্ট (রেফারেন্স _ নিরাপদ 2)
    }
}

পরীক্ষার কোড:

var s = নতুন নিরাপদ ();

সমান্তরাল.ফোর্স (0, 10000000, _ => {s.SafeIncrement1 ();});
সমান্তরাল.ফোর (0, 10000000, _ =>। S.SafeIncrement2 ();});

কনসোল.ওরাইটলাইন (স্ট্রিং.ফর্ম্যাট ("{0} - {1}", এস। সেফ 1, এস। সেফ 2));

উভয় ক্ষেত্রেই ফলাফল সঠিক। প্রথমটি পুরো সংমিশ্রণ ++ অপারেশনের চারদিকে একটি লক রাখে, যখন দ্বিতীয়টি পারমাণবিক ক্রিয়াকলাপের জন্য হার্ডওয়্যার সমর্থন ব্যবহার করে।

ইন্টারলকড সহ উপরের দ্বিতীয় রূপটি নোট করুন nc সংক্ষেপণটি অনেক দ্রুত, তবে এটি নিম্ন স্তরের এবং এটি বাক্সের বাইরে কী করতে পারে তা সীমাবদ্ধ; তবে ইন্টারলকড প্যাকেজের ক্রিয়াকলাপগুলি প্রয়োগ করতে ব্যবহার করা যেতে পারে:

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

উত্তর 2:

দুটি সম্পূর্ণ ভিন্ন জিনিস। থ্রেড সেফ মানে এমনভাবে লিখিত একটি ফাংশন যাতে এটি প্রতিটি থ্রেড অন্য থ্রেডের ক্রিয়াকলাপকে ব্যাহত না করে বহুবার বিভিন্ন থ্রেড দ্বারা বারবার বলা যেতে পারে (উদাহরণস্বরূপ, অন্য কোনও থ্রেড ব্যবহার করে এমন ভেরিয়েবলের মান পরিবর্তন করে)

পারমাণবিক অর্থ (যদি আমি সেখানে পৌঁছে যাই তবে আপনি) যে কোনও বস্তুর এক উদাহরণ তৈরি করতে পারেন - সুতরাং এটি যতবার উল্লেখ করা যায় না কেন, আপনি সর্বদা সেই নজিরটি দেখতে পান (যে কোনও থ্রেড থেকে)


উত্তর 3:

পারমাণবিক ক্রিয়াকলাপ থ্রেড সুরক্ষা অর্জনের একটি উপায় যা মুটেক্সেস বা সেমোফোর্সের মতো কিছু ধরণের লক ব্যবহার করে যা পারমাণবিক ক্রিয়াকলাপ অভ্যন্তরীণভাবে ব্যবহার করে বা অ্যাটিক্স এবং মেমরি বেড়া ব্যবহার করে লক ফ্রি সিঙ্ক্রোনাইজেশন প্রয়োগ করে।

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

হ্যাঁ, এই # পারমাণবিক ডেটা প্রকারের মধ্যে সি # তে লেখা থ্রেড নিরাপদ তবে এটি আপনি থ্রেডে ব্যবহার করেন এমন ফাংশনটি নিরাপদ করে না। এটি কেবলমাত্র এটি নিশ্চিত করে যে একটি একক লেখাই সঠিকভাবে সম্পাদন করা হয়েছে এমনকি যদি দ্বিতীয় থ্রেডটি "একই সময়ে" অ্যাক্সেস করে। কখনও কম নয়, বর্তমান থ্রেড থেকে পরবর্তী পঠনটি আলাদা থ্রেড হিসাবে পূর্বে লিখিত মানটি এটিতে লেখা থাকতে পারে তা নিশ্চিত করা হয় না, কেবলমাত্র মানটি পঠনযোগ্য is