Interlocked.Increment () function explain (reprint)

 Original Address

    class Program
    {
        static object lockObj = new object();
        static int maxTask = 5;
        static int currentCount = 0;
        //假设要处理的数据源
        static List<int> numbers = Enumerable.Range(5, 10).ToList();
        static void Main(string[] args)
        {
            var A = numbers;
            TaskContinueDemo();
            Console.ReadKey();
        }
        private static void TaskContinueDemo()
        {
            while (currentCount < maxTask && numbers.Count > 0)
            {
                lock (lockObj)
                {
                    if (currentCount < maxTask && numbers.Count > 0)
                    {
                        Interlocked.Increment(ref currentCount);//以原子操作的形式实现递增
                        var task = Task.Factory.StartNew(() =>
                        {
                            var number = numbers.FirstOrDefault();
                            if(Number> 0 )
                            { 
                                numbers.Remove (Number); 
                                the Thread.Sleep ( 1000 ); // assumed to be performed a second 
                                Console.WriteLine ( " the Task ID. 1 {0} {Time} {dealNumber the currentCount {2}}. 3 " , Task.CurrentId, the DateTime.Now, the currentCount, number);
                                 IF (Rand () == 0 ) // simulation execution abnormality 
                                { 
                                    numbers.Add (number); // because abnormal, so there need to reload number pending collection 
                                    Console .WriteLine ( "number {0} add because Exception", number);
                                    throw new Exception();
                                }
                            }
                        }, TaskCreationOptions.LongRunning).ContinueWith(t =>
                        {//在ContinueWith中恢复计数
                            Interlocked.Decrement(ref currentCount);
                            Console.WriteLine("Continue Task id {0} Time{1} currentCount{2}", Task.CurrentId, DateTime.Now, currentCount);
                            TaskContinueDemo();
                        });
                    }
                }
            }
        }
        private static int Rand(int maxNumber = 5)
        {
            return Math.Abs(Guid.NewGuid().GetHashCode()) % maxNumber;
        }

    }

 

InterLockedIncrement and InterLockedDecrement 

atomicity subtraction number. What is atomic addition and subtraction of it? 

For example: if a variable value Long = 0 ; 

First talk about subtraction operation under normal conditions: value + = . 1 ; 

. 1 : System Value takes a value from the space and a space for storing the dynamically generated value is taken out; 

2 : the values and taken out as an adder, and the back space and overwrite the original value of value. The addition is completed. 


If at this time there are two Thread, are designated as threadA, threadB. 

1 : Value ThreadA removed from the storage space, is 0; 

2 : Value ThreadB removed from the storage space, is 0; 

. 3 : ThreadA the values and taken out as an adder, and the back space and overwrite the original Value value. End addition, the Value = . 1 . 

. 4 : ThreadB taken out of the value of 1 for addition, and the back space and overwrite the original value of Value. End addition, the Value = . 1 . 

Finally Value = 1, While the right should be 2; this is where the problem lies, InterLockedIncrement to ensure that no other thread can access when a thread access the variable. Similarly InterLockedDecrement. 

InterlockedDecrement LONG (    
      LPLONG lpAddend        //    variable address    
);    
belong interlock function, used within the same process, the need for a shared variable, subtract the time,    
to prevent other threads access the variable, is one way to achieve synchronization of threads ( interlock function)  
   
must first understand the multi-thread synchronization, resource sharing (simultaneous access problem with global variables), otherwise it is difficult to understand.   
     
the Result    = InterlockedDecrement (& someInt)    
     
if you do not consider multithreading is actually the Result    = someInt -    1 ;    
     
but given the complexity of multi-threading on a number of issues. That will not be easy if I want to get the desired results.   
     
result    = someInt -    1 ;    
     
for example:    
someInt if == 1 ;    
expected results of course result== 0 ;    
     
however, the global variable is the case if SomeInt a full share is not the same.   
C language of " the Result = SomeInt - 1; "    
in the actual implementation process, there are several instructions in the instruction execution, other threads may change SomeInt value, the real results are inconsistent with your expectations.   
     
So InterlockedDecrement ( & execution SomeInt) is such that    
{    
      __ prevent other threads access ( & SomeInt) this address    
     
      someInt    - ;    
         
      the Move EAX, someInt;    //    set the return value, the return value of C ++ functions are placed in EAX in    
     
      __ other threads open access ( & someInt) this address    
}    
     
, but only a few actually prefix instruction can be completed, the above description is enlarged.   
     
You might say, it is necessary to do ?    In general, the probability of error is small, but prevention is always necessary  
if you do not consider multithreading   
the Result   InterlockedDecrement = (& SomeInt);    
that is the Result    = SomeInt -    1 ;    
if SomeInt == 1 , the Result certain == 0 ;    
     
however, if multiple threads are shared among threads SomeInt global variables, the situation is not so simple.   
Result    = someInt -    . 1 ;    
in the CPU, to execute several instructions. SomeInt middle instruction may be modified threads. That the actual result is not what you expected result.   
     
InterlockedDecrement ( & someInt)    
amplification procedure, as follows:    
{    
      __ prevent other threads from accessing    & someInt address;    
     
      someInt    - ;    
         
      /// // someInt another thread does not modify the value here. !!!!!!    
     
      mov EAX, someInt;    //C ++ function will always return in EAX.   
         
      __ open other threads access    & someInt address;    
}    
     
actual CPU execution only a few prefix instructions (586 instructions)    
     
you would say, it is necessary to do the probability of error is small, but the error always need to guard against?. Of course you can use other mechanisms to achieve multi-threaded, but are not so simple, so Interlocked ... functions necessary to provide.

 

Guess you like

Origin www.cnblogs.com/macT/p/12058411.html