诡异的线程同步有关问题()

诡异的线程同步问题(高手进)
程序如下:

#include <iostream>
#include <process.h>
#include <Windows.h>
using namespace std;

long total = 0;
const int M = 100000;

unsigned __stdcall ThreadProc(void*)
{
for(long i = 1; i <= M; i++)
total += 1;
return 0;
}

int main(int argc, char* argv[])
{
const int N = 10000;
HANDLE h[2];
int min = 0;
int max = 0;

//统计N次total的最小和最大值
for(int i = 0; i < N; i++)
{
total = 0;
h[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);
h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);

//等待两个线程都结束
WaitForMultipleObjects(2, h, TRUE, INFINITE);

CloseHandle(h[0]);
CloseHandle(h[1]);

if(min == 0)
min = total;
if(total < min)
{
min = total;
}
if(total > max)
{
max = total;
}
}
cout << "(" << min << "," << max << ")";
return 0;
}


total += 1;的汇编码为:

1,         mov         eax,dword ptr [total (0E69148h)] 
2,         add          eax,1 
3,         mov         dword ptr [total (0E69148h)],eax 


线程在第3行汇编码之前切换就会导致total的值不准确。
比如第一个线程在total为0时执行完第1行汇编码,然后切换到线程2。
等待线程2执行完之后再将eax的值写入到total的内存区,total的值将变成1。
线程1执行完之后total的值为M。
按我的分析total的范围应该是[M,2M]的闭区间。
可统计的结果显示min有可能小于M,尤其的是M越大越明显,很诡异吧!!!
而且我也测试过,每次都是两个线程结束后统计的min和max,所以找不到原因了,求解答。。。
------解决方案--------------------
计算有误,分两列看数据吧 一列为totaol 值一列为寄存器
a线程
0  1
跳转b(极端例子线程切换不可估计)
计算到
9999 9999,寄存器数据写入total 
跳转到a
寄存器数据存入total,total数据变为1
1,1
线程切换到b
1,1
切换到a
10000,10000,a计算结束了
切换到b,b也计算结束了
1,2
b数据写入total值为2.
所以最小值不一定为m


------解决方案--------------------
volatile只是跳过寄存器而已。你这里是内存的问题,volatile避免不了。
主要问题还是线程x的写什么时候能被线程y看到。最坏情况下,线程1:写了1;线程2:之前一直写到M-1,然后再看到线程1的1,最后一下+1变成2;线程1:再一直写到M-1,然后再看到线程2最后的一个2,最后一下+1变成3。然后主线程看到3。
所以M无论多大,答案是3也是有理论可能的。

当然这是多核的共享内存问题。单核上的确线程再怎么切换也不会小于M,但是那是单核世界。