诡异的线程同步问题(高手进)

passion_wu128 passion_wu128 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
程序如下:

#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,所以找不到原因了,求解答。。。
...全文

相关推荐

评论 23
收藏 已收藏
分享
返回顶部
passion_wu128
C++ 语言 65,214 成员 250,514 内容