第一种线程同步机制:只利用一个全局变量来判断是否有线程正在使用critical section,这样就有可能出现,两个线程同时判断当前没有线程正在使用critical section的情况,从而同时进入了critical section。
实际结果输出:偶尔出现加减交替的情况,即偶尔出现了两个线程同时进入critical section的情况。
#include <stdio.h>
#include <Windows.h>
#include <iostream>
using namespace std;
int id = 0;
int x = 0;
int length = 10000;
DWORD WINAPI cc(PVOID pvParam);
bool test(int &id) {
if (id == 0) {
id = 1;
return true;
}
else
return false;
}
int main(void)
{
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, cc, (PVOID)id, 0, &dwThreadID);
while (1) {
while (test(id));
for (int i = 0; i < length; i++)
{
x++;
}
printf("0 : %d\n\n", x);
id = 0;
}
}
DWORD WINAPI cc(PVOID pvParam) {
while (1) {
while (test(id));
for (int i = 0; i < length; i++)
{
x--;
}
printf("1 : %d\n\n", x);
id = 0;
}
}
第二种线程同步机制:在每个线程中都判断了另一个线程是否正在使用critical section。
实验结果输出:基本上第一个线程执行一次就到第二个线程执行一次。
#include <iostream>
#include <Windows.h>
#include <stdio.h>
using namespace std;
int id = 0;
int x = 0;
int length = 10000;//重复10000次是为了让线程同步的问题出现得更明显
bool flag[2] = { false, false };
DWORD WINAPI cc(PVOID pvParam);
int main(void)
{
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, cc, (PVOID)id, 0, &dwThreadID);
while (1) {
id = 1;
flag[0] = true;
//判断第二个进程是否正在使用全局变量x
while (flag[1] && id);
//critical section
for (int i = 0; i < length; i++)
{
x++;
}
printf("0 : %d\n\n", x);
flag[0] = false;
}
}
DWORD WINAPI cc(PVOID pvParam) {
while (1) {
id = 0;
flag[1] = true;
//判断第一个进程是否正在使用全局变量x
while (flag[0] && id == 0);
//critical section
for (int i = 0; i < length; i++)
{
x--;
}
printf("1 : %d\n\n", x);
flag[1] = false;
}
}
结论:在处理线程同步的问题时,要设计更加严谨的判断机制。
版权声明:本文为sinat_14826343原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。