c# - ম্যানুয়েল রিসেটভেন্ট এবং অটো রিসেট ইভা এর মধ্যে পার্থক্য কী? নেটের মধ্যে?




.net multithreading (7)

জোসেফ আলাবাহারি দ্বারা সি # 3.0 নথেল বই থেকে নেওয়া

সি # মধ্যে থ্রেডিং - ফ্রি ই বই

একটি ম্যানুয়াল রিসেটভেন্ট অটোResetEvent একটি বৈচিত্র্য। কোনও থ্রেডটি ওয়েটোনে কল করার মাধ্যমে এটি স্বয়ংক্রিয়ভাবে রিসেট হয় না এবং এটি একটি গেটের মতো কাজ করে: কলিং সেট গেটটি খোলে, গেটে অপেক্ষা করে যে কোনও থ্রেডকে অনুমতি দেয়; কলিং পুনরায় সেট গেট বন্ধ, যার ফলে, সম্ভবত, তার পরবর্তী খোলা পর্যন্ত accumulate ওয়েটার একটি সারি।

"স্পিন-স্লিপিং" এর সাথে মিল রেখে বুলিয়ান "গেট ওপেন" ক্ষেত্রটি (উদ্বায়ী শব্দ দিয়ে ঘোষিত) এর সাথে এই কার্যকারিতাটি অনুকরণ করতে পারে - বারবার পতাকা পরীক্ষা করে এবং অল্প সময়ের জন্য ঘুমানো।

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

আমি এই উপর ডকুমেন্টেশন পড়া আছে এবং আমি মনে করি আমি বুঝতে। AutoResetEvent যখন AutoResetEvent পাস করে তখন AutoResetEvent রিসেট করে। event.WaitOne() , তবে একটি ManualResetEvent নয়।

এটা কি সঠিক?


আমি ManualResetEvent AutoResetEvent ManualResetEvent বনাম AutoResetEvent ManualResetEvent বুদ্ধি বোঝার জন্য সহজ উদাহরণ তৈরি।

AutoResetEvent : আপনি 3 শ্রমিক থ্রেড আছে অনুমান করা যাক। যদি সেই থ্রেডগুলির মধ্যে WaitOne() কল করবে তবে অন্য সকল 2 টি থ্রেড কার্যকর হবে এবং সংকেতটির জন্য অপেক্ষা করবে। আমি অপেক্ষা করছি তারা WaitOne() ব্যবহার WaitOne() । এটার মত; যদি আমি কাজ করি না, কেউ কাজ করে না। প্রথম উদাহরণে আপনি দেখতে পারেন

autoReset.Set();
Thread.Sleep(1000);
autoReset.Set();

যখন আপনি Set() কল করবেন তখন সমস্ত থ্রেড কাজ করবে এবং সংকেতটির জন্য অপেক্ষা করবে। 1 সেকেন্ড পর আমি দ্বিতীয় সংকেত প্রেরণ করছি এবং তারা কার্যকর এবং অপেক্ষা করুন ( WaitOne() )। এই ছেলেরা ফুটবল দলের খেলোয়াড়দের কথা ভাবুন এবং যদি একজন খেলোয়াড় বলে যে আমি যতক্ষণ না ম্যানেজার আমাকে ডাকে ততক্ষণ অপেক্ষা করব এবং অন্যরা অপেক্ষা করবে যতক্ষণ না ম্যানেজার তাদেরকে চালিয়ে যেতে বলে। ( Set() )

public class AutoResetEventSample
{
    private AutoResetEvent autoReset = new AutoResetEvent(false);

    public void RunAll()
    {
        new Thread(Worker1).Start();
        new Thread(Worker2).Start();
        new Thread(Worker3).Start();
        autoReset.Set();
        Thread.Sleep(1000);
        autoReset.Set();
        Console.WriteLine("Main thread reached to end.");
    }

    public void Worker1()
    {
        Console.WriteLine("Entered in worker 1");
        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker1 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
    public void Worker2()
    {
        Console.WriteLine("Entered in worker 2");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker2 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
    public void Worker3()
    {
        Console.WriteLine("Entered in worker 3");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker3 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
}

এই উদাহরণে আপনি স্পষ্টভাবে দেখতে পারেন যে যখন আপনি প্রথম Set() আঘাত করেন Set() এটি সমস্ত থ্রেডকে যেতে দেয়, তারপর 1 সেকেন্ডের পরে এটি সমস্ত থ্রেডকে অপেক্ষা করতে নির্দেশ করে! যত তাড়াতাড়ি আপনি তাদের আবার সেট করুন WaitOne() না তারা WaitOne() ভিতরে কল WaitOne() , তারা চলতে থাকবে কারণ আপনাকে তাদের সকল বন্ধ করার জন্য Reset() কল করতে হবে।

manualReset.Set();
Thread.Sleep(1000);
manualReset.Reset();
Console.WriteLine("Press to release all threads.");
Console.ReadLine();
manualReset.Set();

কোনও খেলোয়াড় আহত না হওয়া পর্যন্ত এবং রেফারি / খেলোয়াড়দের সম্পর্ক সম্পর্কে এটি আরও বেশি সম্পর্কিত এবং অন্যদের খেলার জন্য অপেক্ষা করা চালিয়ে যেতে হবে। রেফারি বলে অপেক্ষা করে ( Reset() ) তাহলে সমস্ত খেলোয়াড় পরবর্তী সংকেত পর্যন্ত অপেক্ষা করবে।

public class ManualResetEventSample
{
    private ManualResetEvent manualReset = new ManualResetEvent(false);

    public void RunAll()
    {
        new Thread(Worker1).Start();
        new Thread(Worker2).Start();
        new Thread(Worker3).Start();
        manualReset.Set();
        Thread.Sleep(1000);
        manualReset.Reset();
        Console.WriteLine("Press to release all threads.");
        Console.ReadLine();
        manualReset.Set();
        Console.WriteLine("Main thread reached to end.");
    }

    public void Worker1()
    {
        Console.WriteLine("Entered in worker 1");
        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker1 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
    public void Worker2()
    {
        Console.WriteLine("Entered in worker 2");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker2 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
    public void Worker3()
    {
        Console.WriteLine("Entered in worker 3");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker3 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
}

শুধু কল্পনা করুন যে AutoResetEvent WaitOne() একটি একক পারমাণবিক অপারেশন হিসাবে WaitOne() এবং Reset() কে সঞ্চালিত করে।


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


হ্যাঁ। এটি একটি Tollbooth এবং একটি দরজা মধ্যে পার্থক্য মত। ManualResetEvent দরজা, যা ম্যানুয়ালি বন্ধ (রিসেট) করতে হবে। AutoResetEvent একটি AutoResetEvent , একটি গাড়ী যেতে এবং স্বয়ংক্রিয়ভাবে পরের এক আগে পেতে পারেন অনুমতি দেয়।


হ্যাঁ। এটি একেবারে সঠিক।

আপনি রাজ্য নির্দেশ করতে একটি উপায় হিসাবে ম্যানুয়াল রিসেটভেন্ট দেখতে পারে। কিছু (সেট) বা বন্ধ (রিসেট) হয়। কিছু সময়কাল সঙ্গে একটি সংঘর্ষ। যে রাষ্ট্র ঘটতে জন্য অপেক্ষা কোন থ্রেড এগিয়ে যেতে পারেন।

একটি AutoResetEvent একটি সংকেত আরো তুলনীয়। কিছু একটা ঘটেছে যে একটি এক শট ইঙ্গিত। কোন সময়কাল ছাড়া একটি সংঘটন। সাধারণতঃ তবে প্রয়োজনীয় কিছু "কিছু" ছোট নয় এবং একক থ্রেড দ্বারা পরিচালিত হওয়ার প্রয়োজন হয় - সুতরাং একক থ্রেডের পরে স্বয়ংক্রিয় রিসেট ইভেন্টটি খেয়ে ফেলে।


অটোResetEvent মেমরি একটি বুলিয়ান পরিবর্তনশীল বজায় রাখে। যদি বুলিয়ান ভেরিয়েবলটি মিথ্যা হয় তবে এটি থ্রেডকে ব্লক করে এবং বুলিয়ান ভেরিয়েবলটি সত্য হলে এটি থ্রেডটিকে আনলক করে।

যখন আমরা একটি AutoResetEvent অবজেক্টটি তাত্ক্ষণিক করি, আমরা কন্সট্রকটারে বুলিয়ান মানের ডিফল্ট মান পাস করি। নীচে একটি AutoResetEvent বস্তুর তাত্ক্ষণিক সিনট্যাক্স হয়।

AutoResetEvent autoResetEvent = new AutoResetEvent(false);

WaitOne পদ্ধতি

এই পদ্ধতিটি বর্তমান থ্রেডটিকে ব্লক করে এবং অন্যান্য থ্রেড দ্বারা সংকেতটির জন্য অপেক্ষা করে। WaitOne পদ্ধতিটি বর্তমান থ্রেডটিকে একটি ঘুমের থ্রেড অবস্থায় রাখে। প্রত্যক্ষ প্রতীকটি যদি ফেরৎ ফেরত দেয় তবে WaitOne পদ্ধতিটি সত্য ফিরে আসে।

autoResetEvent.WaitOne();

WaitOne পদ্ধতির দ্বিতীয় ওভারলোড নির্দিষ্ট সেকেন্ডের জন্য অপেক্ষা করুন। এটি কোনো সংকেত থ্রেড তার কাজ চলতে না হলে।

static void ThreadMethod()
{
    while(!autoResetEvent.WaitOne(TimeSpan.FromSeconds(2)))
    {
        Console.WriteLine("Continue");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }

    Console.WriteLine("Thread got signal");
}

আমরা আর্গুমেন্ট হিসাবে 2 সেকেন্ড পাস করে WaitOne পদ্ধতি বলা। যখন লুপে, এটি 2 সেকেন্ডের জন্য সংকেতটির জন্য অপেক্ষা করে তবে এটি তার কাজটি চালিয়ে যায়। যখন থ্রেডটি সংকেত পায় তখন WaitOne সত্য ফিরে আসে এবং লুপ থেকে বেরিয়ে আসে এবং "থ্রেড পেয়েছে" মুদ্রণ করে।

পদ্ধতি সেট করুন

অটোResetEvent সেট পদ্ধতি তার কাজ এগিয়ে যাওয়ার জন্য অপেক্ষা থ্রেড সংকেত পাঠানো। নীচে সেট পদ্ধতি কলিং এর সিনট্যাক্স।

autoResetEvent.Set();

ম্যানুয়াল ResetEvent মেমরি একটি বুলিয়ান পরিবর্তনশীল বজায় রাখে। যখন বুলিয়ান ভেরিয়েবলটি মিথ্যা হয় তখন এটি সমস্ত থ্রেডকে ব্লক করে এবং বুলিয়ান ভেরিয়েবলটি সত্য হলে এটি সমস্ত থ্রেডকে অবরোধ করে।

যখন আমরা একটি ম্যানুয়াল রিসেটভেন্টকে তাত্ক্ষণিক করি, তখন আমরা ডিফল্ট বুলিয়ান মান দিয়ে এটি আরম্ভ করি।

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

উপরের কোডে, আমরা ম্যানুয়াল রিসেট ইভেন্টকে মিথ্যা মান দিয়ে শুরু করি, এর মানে ওয়েটঅন পদ্ধতিতে কল করা সমস্ত থ্রেডগুলি কিছু থ্রেড সেট () পদ্ধতি কল না হওয়া অবধি অবরোধ করবে।

আমরা ম্যানুয়াল রিসেট ইভেন্টকে সত্য মান দিয়ে শুরু করলে, ওয়েটোনে পদ্ধতি কল করে এমন সকল থ্রেড ব্লক এবং এগিয়ে যেতে মুক্ত হবে না।

অপেক্ষা করুন পদ্ধতি

এই পদ্ধতিটি বর্তমান থ্রেডটিকে ব্লক করে এবং অন্যান্য থ্রেড দ্বারা সংকেতটির জন্য অপেক্ষা করে। যদি এটি একটি সংকেত গ্রহণ করে তবে এটি মিথ্যা ফেরত দেয়।

নীচে WaitOne পদ্ধতি কলিং এর সিনট্যাক্স।

manualResetEvent.WaitOne();

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

নীচে সময় বিরতি সঙ্গে WaitOne পদ্ধতি কলিং এর সিনট্যাক্স।

bool isSignalled = manualResetEvent.WaitOne(TimeSpan.FromSeconds(5));

আমরা WaitOne পদ্ধতিতে 5 সেকেন্ড নির্দিষ্ট করেছি। যদি ম্যানুয়াল রিসেট ইভেন্ট বস্তু 5 সেকেন্ডের মধ্যে কোন সংকেত পায় না, তবে isSignalled পরিবর্তনশীলটি মিথ্যাতে সেট করুন।

পদ্ধতি সেট করুন

এই পদ্ধতি সব অপেক্ষা থ্রেড সংকেত পাঠানোর জন্য ব্যবহৃত হয়। সেট () পদ্ধতি ম্যানুয়ালResetEvent বস্তু বুলিয়ান ভেরিয়েবলটিকে সত্য হিসাবে সেট করে। সমস্ত অপেক্ষা থ্রেড unblocked এবং আরও এগিয়ে যান।

নীচে সেট () পদ্ধতি কলিংয়ের সিনট্যাক্স।

manualResetEvent.Set();

পদ্ধতি রিসেট করুন

একবার আমরা ম্যানুয়াল রিসেটেভেন্ট বস্তুতে সেট () পদ্ধতিটি কল করলে, তার বুলিয়ানটি সত্যই রয়ে যায়। মানটি পুনরায় সেট করতে আমরা রিসেট () পদ্ধতি ব্যবহার করতে পারি। রিসেট পদ্ধতিটি বুলিয়ান মানটিকে মিথ্যাতে পরিবর্তন করে।

নীচে রিসেট পদ্ধতি কলিং এর সিনট্যাক্স।

manualResetEvent.Reset();

আমরা থ্রেডগুলিকে একাধিকবার সংকেত পাঠাতে চাইলে সেট পদ্ধতি কল করার পরে আমাদের অবিলম্বে রিসেট পদ্ধতি কল করতে হবে।







manualresetevent