FAQ multithreading in C #

1. resource competition

When multiple threads execute simultaneously while the need for global variables read-write operations, resource competition prone to problems, resulting in many cases run the results appear. Will be described in the following example:

 

        private static CancellationTokenSource cs = new CancellationTokenSource();
        private static int num = 5;
        private static object obj = new object();

        static void Main(string[] args)
        {
            Console.WriteLine("Main Start....");
            Task t1 = Task.Factory.StartNew(Test);
            Task t2 = Task.Factory.StartNew(Test);
            Task.WaitAll(new Task[] { t1, t2 });
            cs.Dispose();
            Console.WriteLine("Main end....");
            Console.ReadLine();
        }

        static void Test()
        {
            the while (! cs.IsCancellationRequested)     // whether to invoke the Cancel 
            {
                Console.WriteLine("TaskId {0} Excute other code....num is {1}",Task.CurrentId,num);
                if(num == 5){
                    The Thread.Sleep ( 50 );         // for easy viewing add delay 
                    NUM ++ ;                    
                    Console.WriteLine("TaskId {0} and Num is {1}", Task.CurrentId, num);
                    if (!cs.IsCancellationRequested)
                    {
                        cs.Cancel ();        // cancel 
                    }
                }
            }
        }

 In most cases, results are as follows:

Main Start....
TaskId 1 Excute other code....num is 5
TaskId 2 Excute other code....num is 5
TaskId 2 and Num is 6
TaskId 1 and Num is 7
Main end....

Task 1 First run to Thread.Sleep ( 50), wait 50ms, cpu start to run scheduled tasks 2 Thread.Sleep ( 50) . Then run the task 1 num ++, and outputs the result to the console num = 6, then task 2 run num ++, and outputs to the console num = 7. But sometimes this results appear below:

Main Start....
TaskId 1 Excute other code....num is 5
TaskId 2 Excute other code....num is 5
TaskId 2 and Num is 7
TaskId 1 and Num is 7
Main end....

Task 1 First run to Thread.Sleep ( 50), wait 50ms, cpu start to run scheduled tasks 2 Thread.Sleep ( 50). Then run the task 1 num ++, cpu scheduled task 2 starts immediately to run num ++, and outputs to the console num = 7, and finally to a scheduled task console output num = 7.

 Solution: Just add thread lock lock, it will only be the first operating results, as follows:

        static void Test()
        {
            the while (! cs.IsCancellationRequested)     // whether to invoke the Cancel 
            {
                Console.WriteLine("TaskId {0} Excute other code....num is {1}",Task.CurrentId,num);
                if(num == 5){
                    The Thread.Sleep ( 50 );         // for easy viewing delay added 
                    Lock (obj) // only one thread can operate
                    {
                        a ++ ;                    
                        Console.WriteLine("TaskId {0} and Num is {1}", Task.CurrentId, num);
                    }
                    if (!cs.IsCancellationRequested)
                    {
                        cs.Cancel ();        // cancel 
                    }
                }
            }
        }

 2. Thread Deadlock

There are at least two threads are suspended, waiting for the other to unlock the thread will wait indefinitely.

 

        private static int num = 5;
        private static object obj1 = new object();
        private static object obj2 = new object();

        static void Main(string[] args)
        {
            Console.WriteLine("Main Start....");
            Parallel.Invoke (LockTest1, LockTest2);
            Console.WriteLine("Main end....");
            Console.ReadLine();
        }

        static  void LockTest1 ()
        {
            lock(obj1){
                lock(obj2){
                    Console.WriteLine("LockTest1 is running");
                }
            }
        }

        static  void LockTest2 ()
        {
            lock (obj2)
            {
                lock (obj1)
                {
                    Console.WriteLine("LockTest2 is running");
                }
            }
        }

 

operation result:

Main Start....
LockTest1 is running
LockTest2 is running
Main end....

Seemingly normal, but this program in a very few cases, there will be a deadlock. For example CPU to run LockTest1 () in Lock (obj1) , they immediately run LockTest2 () in Lock (obj2), then LockTest1 () will wait obj2 unlocked, and LockTest2 () will wait obj1 unlocked, form a deadlock.

 

Solution: In designing the program, regardless of the order of a good lock, or lock timeout defined.

Guess you like

Origin www.cnblogs.com/change-myself/p/11161811.html