标题：InterLockedIncrement
函数原型
自减锁函数定义：
LONG InterlockedDecrement( 　LPLONG lpAddend // variable address 　);
与之相对应的自加锁函数为：
InterLockedIncrement( 　LPLONG lpAddend // variable address 　);
函数功能
[1]InterLockedIncrement and InterLockedDecrement
实现数的原子性加减。什么是原子性的加减呢？
举个例子：如果一个变量 Long value =0;
首先说一下正常情况下的加减操作：value+=1；
1：系统从Value的空间取出值，并动态生成一个空间来存储取出来的值；
2：将取出来的值和1作加法，并且将和放回Value的空间覆盖掉原值。加法结束。
如果此时有两个Thread ，分别记作threadA，threadB。
1：threadA将Value从存储空间取出，为0；
2：threadB将Value从存储空间取出，为0；
3：threadA将取出来的值和1作加法，并且将和放回Value的空间覆盖掉原值。加法结束，Value=1。
4：threadB将取出来的值和1作加法，并且将和放回Value的空间覆盖掉原值。加法结束，Value=1。
最后Value =1 ，而正确应该是2；这就是问题的所在，InterLockedIncrement 能够保证在一个线程访问变量时其它线程不能访问。同理InterLockedDecrement。
LONG InterlockedDecrement( 
LPLONG lpAddend // variable address 
); 
属于互锁函数，用在同一进程内，需要对共享的一个变量，做减法的时候， 
防止其他线程访问这个变量，是实现线程同步的一种办法（互锁函数）
首先要理解多线程同步，共享资源（同时访问全局变量的问题），否则就难以理解。 
result = InterlockedDecrement（&SomeInt） 
如果不考虑多线程其实就是 result = SomeInt - 1; 
但是考虑到多线程问题就复杂了一些。就是说如果想要得到我预期的结果并不容易。 
result = SomeInt - 1； 
举例说: 
SomeInt如果==1; 
预期的结果result当然==0; 
但是,如果SomeInt是一个全程共享的全局变量情况就不一样了。 
C语言的"result = SomeInt - 1；" 
在实际的执行过程中，有好几条指令，在指令执行过程中，其它线程可能改变SomeInt值，使真正的结果与你预期的不一致。 
所以InterlockedDecrement(&SomeInt)的执行过程是这样的 
{ 
__禁止其他线程访问 (&SomeInt) 这个地址 
SomeInt --; 
move EAX, someInt; // 设定返回值,C++函数的返回值 都放在EAX中, 
__开放其他线程访问 (&SomeInt) 这个地址 
} 
但是实际上只需要几条指令加前缀就可以完成，以上说明是放大的。 
你也许会说，这有必要吗? 一般来说，发生错误的概率不大，但是防范总是必要的
如果不考虑多线程 
result = InterlockedDecrement(&SomeInt); 
就是result = SomeInt - 1; 
如果SomeInt==1,result一定==0; 
但是，在多线程中如果SomeInt是线程间共享的全局变量，情况就不那么简单了。 
result = SomeInt - 1; 
在CPU中，要执行好几条指令。在指令中间有可能SomeInt被线程修改。那实际的结果就不是你预期的结果了。 
InterlockedDecrement(&SomeInt) 
放大的过程，如下: 
{ 
__禁止其他线程访问 &SomeInt 地址； 
SomeInt --; 
/////其他线程不会在这里修改SomeInt值。 !!!!!! 
mov EAX, SomeInt; //C++ 函数返回值 总放在EAX中。 
__开放其他线程访问 &SomeInt 地址； 
} 
实际的CPU执行过程只有几条加前缀的指令(586指令) 
你会说，有必要吗? 出错的概率不大，但是错误总是需要防范的。当然可以用其他多线程机制实现，但是都没有这样简洁，所以Interlocked...函数有必要提供。
示例
[2]Interlocked.Increment 方法：让++成为原子操作；Interlocked.Decrement 方法让--成为原子操作。
什么叫原子操作呢。就是不会被别人打断，因为C#中的一个语句，编译成机器代码后会变成多个语句。
在多线程环境中，线程切换有可能会发生在这多个语句中间。使用Interlocked.Increment,Interlocked.Decrement 可以避免被打断,保证线程安全。
使用Interlocked.Increment 方法和Interlocked.Decrement 方法MSND例子：
using System;
using System.Threading;
class Test
{
static void Main()
{
Thread thread1 = new Thread(new ThreadStart(ThreadMethod));
Thread thread2 = new Thread(new ThreadStart(ThreadMethod));
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
// Have the garbage collector run the finalizer for each
// instance of CountClass and wait for it to finish.
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("UnsafeInstanceCount: {0}" +
"\nSafeCountInstances: {1}",
CountClass.UnsafeInstanceCount.ToString(),
CountClass.SafeInstanceCount.ToString());
}
static void ThreadMethod()
{
CountClass cClass;
// Create 100,000 instances of CountClass.
for(int i = 0; i < 100000; i++)
{
cClass = new CountClass();
}
}
}
class CountClass
{
static int unsafeInstanceCount = 0;//不使用原子操作
static int safeInstanceCount = 0;//使用原子操作
static public int UnsafeInstanceCount
{
get {return unsafeInstanceCount;}
}
static public int SafeInstanceCount
{
get {return safeInstanceCount;}
}
public CountClass()
{
unsafeInstanceCount++;
Interlocked.Increment(ref safeInstanceCount);
}
~CountClass()
{
unsafeInstanceCount--;
Interlocked.Decrement(ref safeInstanceCount);
}
}
不用原子操作例子
class Program
{
static void Main(string[] args)
{
for (int loop = 0; loop < 20; loop++)
{
sum = 0;
Thread t1 = new Thread(Thread1);
Thread t2 = new Thread(Thread2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine("sum = " + sum); // sum = 200000 ?
}
}
static int sum;
static void Thread1()
{
for (int i = 0; i < 100000; i++) sum++;
}
static void Thread2()
{
for (int i = 0; i < 100000; i++) sum++;
}
}
结果：
/*
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 192361
sum = 175155
sum = 200000
sum = 176024
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 200000
sum = 176322
*/
Why the sum is not always 200000?
The reason is that sum++ is not thread safe (see the possible problem).
That is the reason we need Interlocked.Increment(), which guarantees the sum is always 200000.
Thread1 (sum++) Thread2 (sum++)
--------------------------------------------------------------------
mov EAX, dword ptr sum .
inc EAX .
. mov EAX, dword ptr sum // load sum into a register
. inc EAX // increase it
. mov dword ptr sum, EAX // save back
mov dword ptr sum, EAX
--------------------------------------------------------------------
problem: two sum++ are called in different thread,
but the sum is incremented only once.
也就是说因为C#中的一个语句，编译成机器代码后会变成多个语句，线程不安全，sum++的第100次操作就被打断了，而在第200000次++操作结束后CPU才轮询到sum++的第100次操作，这时sum的值就是101，