• C# 线程同步


    1.利用lock, 如:

    public
    class TestThreading { private System.Object lockThis = new System.Object(); public void Process() { lock (lockThis) { // Access thread-sensitive resources. } } }

    2.利用Monitor类, 如:
    
    System.Object obj = (System.Object)x;
    System.Threading.Monitor.Enter(obj);
    try
    {
        DoSomething();
    }
    finally
    {
        System.Threading.Monitor.Exit(obj);
    }
    

    3.利用AutoResetEvent和ManualResetEvent,比如:

    static AutoResetEvent autoEvent;
    
        static void DoWork()
        {
            Console.WriteLine("   worker thread started, now waiting on event...");
            autoEvent.WaitOne();
            Console.WriteLine("   worker thread reactivated, now exiting...");
        }
    
        static void Main()
        {
            autoEvent = new AutoResetEvent(false);
    
            Console.WriteLine("main thread starting worker thread...");
            Thread t = new Thread(DoWork);
            t.Start();
    
            Console.WriteLine("main thread sleeping for 1 second...");
            Thread.Sleep(1000);
    
            Console.WriteLine("main thread signaling worker thread...");
            autoEvent.Set();
        }
    

    4.利用Mutext, Mutex主要用于进程间同步,进程内尽量使用Monitor
    
    class Test
    {
        // Create a new Mutex. The creating thread does not own the
        // Mutex.
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
    
        static void Main()
        {
            // Create the threads that will use the protected resource.
            for(int i = 0; i < numThreads; i++)
            {
                Thread myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
                myThread.Start();
            }
    
            // The main thread exits, but the application continues to
            // run until all foreground threads have exited.
        }
    
        private static void MyThreadProc()
        {
            for(int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }
    
        // This method represents a resource that must be synchronized
        // so that only one thread at a time can enter.
        private static void UseResource()
        {
            // Wait until it is safe to enter.
            mut.WaitOne();
    
            Console.WriteLine("{0} has entered the protected area", 
                Thread.CurrentThread.Name);
    
            // Place code to access non-reentrant resources here.
    
            // Simulate some work.
            Thread.Sleep(500);
    
            Console.WriteLine("{0} is leaving the protected area
    ", 
                Thread.CurrentThread.Name);
    
            // Release the Mutex.
            mut.ReleaseMutex();
        }
    }
    

    5.利用Interlocked, 比如:
    
     class MyInterlockedExchangeExampleClass
        {
            //0 for false, 1 for true.
            private static int usingResource = 0;
    
            private const int numThreadIterations = 5;
            private const int numThreads = 10;
    
            static void Main()
            {
                Thread myThread;
                Random rnd = new Random();
    
                for(int i = 0; i < numThreads; i++)
                {
                    myThread = new Thread(new ThreadStart(MyThreadProc));
                    myThread.Name = String.Format("Thread{0}", i + 1);
    
                    //Wait a random amount of time before starting next thread.
                    Thread.Sleep(rnd.Next(0, 1000));
                    myThread.Start();
                }
            }
    
            private static void MyThreadProc()
            {
                for(int i = 0; i < numThreadIterations; i++)
                {
                    UseResource();
    
                    //Wait 1 second before next attempt.
                    Thread.Sleep(1000);
                }
            }
    
            //A simple method that denies reentrancy.
            static bool UseResource()
            {
                //0 indicates that the method is not in use.
                if(0 == Interlocked.Exchange(ref usingResource, 1))
                {
                    Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
    
                    //Code to access a resource that is not thread safe would go here.
    
                    //Simulate some work
                    Thread.Sleep(500);
    
                    Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
    
                    //Release the lock
                    Interlocked.Exchange(ref usingResource, 0);
                    return true;
                }
                else
                {
                    Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                    return false;
                }
            }
    
        }
    

    6.利用ReaderWriterLockSlim, 比如:
    
    public class Test
    {
        // Declaring the ReaderWriterLock at the class level
        // makes it visible to all threads.
        static ReaderWriterLock rwl = new ReaderWriterLock();
        // For this example, the shared resource protected by the
        // ReaderWriterLock is just an integer.
        static int resource = 0;
    
        const int numThreads = 26;
        static bool running = true;
        static Random rnd = new Random();
    
        // Statistics.
        static int readerTimeouts = 0;
        static int writerTimeouts = 0;
        static int reads = 0;
        static int writes = 0;
    
        public static void Main(string[] args)
        {
            // Start a series of threads. Each thread randomly
            // performs reads and writes on the shared resource.
            Thread[] t = new Thread[numThreads];
            for (int i = 0; i < numThreads; i++)
            {
                t[i] = new Thread(new ThreadStart(ThreadProc));
                t[i].Name = new String(Convert.ToChar(i + 65), 1);
                t[i].Start();
                if (i > 10)
                    Thread.Sleep(300);
            }
    
            // Tell the threads to shut down, then wait until they all
            // finish.
            running = false;
            for (int i = 0; i < numThreads; i++)
            {
                t[i].Join();
            }
    
            // Display statistics.
            Console.WriteLine("
    {0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
                reads, writes, readerTimeouts, writerTimeouts);
            Console.WriteLine("Press ENTER to exit.");
            Console.ReadLine();
        }
    
        static void ThreadProc()
        {
            // As long as a thread runs, it randomly selects
            // various ways to read and write from the shared 
            // resource. Each of the methods demonstrates one 
            // or more features of ReaderWriterLock.
            while (running)
            {
                double action = rnd.NextDouble();
                if (action < .8)
                    ReadFromResource(10);
                else if (action < .81)
                    ReleaseRestore(50);
                else if (action < .90)
                    UpgradeDowngrade(100);
                else
                    WriteToResource(100);
            }
        }
    
        // Shows how to request and release a reader lock, and
        // how to handle time-outs.
        static void ReadFromResource(int timeOut)
        {
            try
            {
                rwl.AcquireReaderLock(timeOut);
                try
                {
                    // It is safe for this thread to read from
                    // the shared resource.
                    Display("reads resource value " + resource); 
                    Interlocked.Increment(ref reads);
                }        
                finally
                {
                    // Ensure that the lock is released.
                    rwl.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                // The reader lock request timed out.
                Interlocked.Increment(ref readerTimeouts);
            }
        }
    
        // Shows how to request and release the writer lock, and
        // how to handle time-outs.
        static void WriteToResource(int timeOut)
        {
            try
            {
                rwl.AcquireWriterLock(timeOut);
                try
                {
                    // It is safe for this thread to read or write
                    // from the shared resource.
                    resource = rnd.Next(500);
                    Display("writes resource value " + resource);
                    Interlocked.Increment(ref writes);
                }        
                finally
                {
                    // Ensure that the lock is released.
                    rwl.ReleaseWriterLock();
                }
            }
            catch (ApplicationException)
            {
                // The writer lock request timed out.
                Interlocked.Increment(ref writerTimeouts);
            }
        }
    
        // Shows how to request a reader lock, upgrade the
        // reader lock to the writer lock, and downgrade to a
        // reader lock again.
        static void UpgradeDowngrade(int timeOut)
        {
            try
            {
                rwl.AcquireReaderLock(timeOut);
                try
                {
                    // It is safe for this thread to read from
                    // the shared resource.
                    Display("reads resource value " + resource); 
                    Interlocked.Increment(ref reads);
    
                    // If it is necessary to write to the resource,
                    // you must either release the reader lock and 
                    // then request the writer lock, or upgrade the
                    // reader lock. Note that upgrading the reader lock
                    // puts the thread in the write queue, behind any
                    // other threads that might be waiting for the 
                    // writer lock.
                    try
                    {
                        LockCookie lc = rwl.UpgradeToWriterLock(timeOut);
                        try
                        {
                            // It is safe for this thread to read or write
                            // from the shared resource.
                            resource = rnd.Next(500);
                            Display("writes resource value " + resource);
                            Interlocked.Increment(ref writes);
                        }        
                        finally
                        {
                            // Ensure that the lock is released.
                            rwl.DowngradeFromWriterLock(ref lc);
                        }
                    }
                    catch (ApplicationException)
                    {
                        // The upgrade request timed out.
                        Interlocked.Increment(ref writerTimeouts);
                    }
    
                    // When the lock has been downgraded, it is 
                    // still safe to read from the resource.
                    Display("reads resource value " + resource); 
                    Interlocked.Increment(ref reads);
                }        
                finally
                {
                    // Ensure that the lock is released.
                    rwl.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                // The reader lock request timed out.
                Interlocked.Increment(ref readerTimeouts);
            }
        }
    
        // Shows how to release all locks and later restore
        // the lock state. Shows how to use sequence numbers
        // to determine whether another thread has obtained
        // a writer lock since this thread last accessed the
        // resource.
        static void ReleaseRestore(int timeOut)
        {
            int lastWriter;
    
            try
            {
                rwl.AcquireReaderLock(timeOut);
                try
                {
                    // It is safe for this thread to read from
                    // the shared resource. Cache the value. (You
                    // might do this if reading the resource is
                    // an expensive operation.)
                    int resourceValue = resource;
                    Display("reads resource value " + resourceValue); 
                    Interlocked.Increment(ref reads);
    
                    // Save the current writer sequence number.
                    lastWriter = rwl.WriterSeqNum;
    
                    // Release the lock, and save a cookie so the
                    // lock can be restored later.
                    LockCookie lc = rwl.ReleaseLock();
    
                    // Wait for a random interval (up to a 
                    // quarter of a second), and then restore
                    // the previous state of the lock. Note that
                    // there is no time-out on the Restore method.
                    Thread.Sleep(rnd.Next(250));
                    rwl.RestoreLock(ref lc);
    
                    // Check whether other threads obtained the
                    // writer lock in the interval. If not, then
                    // the cached value of the resource is still
                    // valid.
                    if (rwl.AnyWritersSince(lastWriter))
                    {
                        resourceValue = resource;
                        Interlocked.Increment(ref reads);
                        Display("resource has changed " + resourceValue);
                    }
                    else
                    {
                        Display("resource has not changed " + resourceValue);
                    }
                }        
                finally
                {
                    // Ensure that the lock is released.
                    rwl.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                // The reader lock request timed out.
                Interlocked.Increment(ref readerTimeouts);
            }
        }
    
        // Helper method briefly displays the most recent
        // thread action. Comment out calls to Display to 
        // get a better idea of throughput.
        static void Display(string msg)
        {
            Console.Write("Thread {0} {1}.       
    ", Thread.CurrentThread.Name, msg);
        }
    }
    

  • 相关阅读:
    20145331 《信息安全系统设计基础》第11周学习总结
    20145331魏澍琛《信息安全系统设计基础》第10周学习总结
    20145331 《信息安全系统设计基础》实验四 外设驱动设计
    20145331 《信息安全系统设计基础》实验二 固件设计
    20145330 《网络对抗》逆向及BOF基础实践
    20145330 《信息安全系统设计基础》课程总结
    20145330 《信息安全系统设计基础》第14周学习总结
    20145330 《信息安全系统设计基础》第13周学习总结
    20145330 《信息安全系统设计基础》第12周学习总结
    20145216 20145330 《信息安全系统设计基础》 实验五 简单嵌入式WEB 服务器实验
  • 原文地址:https://www.cnblogs.com/muzizongheng/p/3170859.html
Copyright © 2020-2023  润新知