I met a strange problem while studying the Peterson Algorithm. When I finish my program, I was told that I should restrict that two particular threads (thread1 and thread2) to a single CPU core (I don't exactly know why I should do this, but my teacher told me that if I want to run two mutual exclusion processes with single resources without conflict, multi-core CPU may cause bug so I should restrict them to a single core) so I add the SetThreadAffinityMask()
to do this.
But after I added this function, my code doesn't work, it was stuck into a infinite loop in thread1, not like the result before I add this function, which is work as well as I expected.
Here's my code
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
int nAccount1 = 0, nAccount2 = 0;
DWORD start, end;
int flag = 0;
int Process[2] = { 0 };
int Turn = 0;
DWORD WINAPI ThreadExecutive_1(LPVOID lpParameter) {
int nLoop = 0;
int nTemp1, nTemp2, nRandom;
int* pID = (int*)lpParameter;
//printf("Thread: %d Built successfully!\n", *pID);
do {
Process[0] = 1;
Turn = 1;
while (Process[1] == 1 && Turn == 1);
nTemp1 = nAccount1;
nTemp2 = nAccount2;
nRandom = rand();
nAccount1 = nTemp1 + nRandom;
nAccount2 = nTemp2 - nRandom;
Process[0] = 0;
nLoop++;
if (nLoop % 100000 == 0) {
// printf("here thread %d\n", *pID);
}
} while (nLoop < 1000000);
//printf("Thread%d was terminated Result:nAccount1 = %d, nAccount2 = %d\n", *pID, nAccount1, nAccount2);
flag++;
return 0;
}
DWORD WINAPI ThreadExecutive_2(LPVOID lpParameter) {
int nLoop = 0;
int nTemp1, nTemp2, nRandom;
int* pID = (int*)lpParameter;
printf("Thread: %d Built successfully!\n", *pID);
do {
Process[1] = 1;
Turn = 0;
while (Process[0] == 1 && Turn == 0);
nTemp1 = nAccount1;
nTemp2 = nAccount2;
nRandom = rand();
nAccount1 = nTemp1 + nRandom;
nAccount2 = nTemp2 - nRandom;
Process[1] = 0;
nLoop++;
if (nLoop % 100000 == 0) {
printf("here thread %d\n", *pID);
}
} while (nLoop < 1000000);
printf("Thread%d was terminated Result:nAccount1 = %d, nAccount2 = %d\n", *pID, nAccount1, nAccount2);
flag++;
return 0;
}
int main()
{
start = GetTickCount();
printf("===============Peterson Algorithm================\n");
HANDLE handle1, handle2;
int Thread1 = 1;
int Thread2 = 2;
//===========This is where the problem occourred===================
handle1 = CreateThread(NULL, 0, ThreadExecutive_1, &Thread1, 0, NULL);
SetThreadAffinityMask(handle1, 0x00000001);
handle2 = CreateThread(NULL, 0, ThreadExecutive_2, &Thread2, 0, NULL);
SetThreadAffinityMask(handle2, 0x00000001);
//===========This is where the problem occourred===================
if (handle1 == NULL) {
printf("Handle1 build failed\n");
exit(0);
}
if (handle2 == NULL) {
printf("Handle2 build failed\n");
exit(0);
}
CloseHandle(handle1);
CloseHandle(handle2);
while (1) {
if (flag == 2) {
break;
}
}
end = GetTickCount();
printf("Execution time : %d\n", (end - start));
system("pause");
return 0;
}
Here are the results. Without SetThreadAffinityMask()
:
===============Peterson Algorithm================
Thread: 1 Built successfully!
Thread: 2 Built successfully!
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
here thread 2
here thread 1
Thread1 was terminated Result:nAccount1 = -1621397855, nAccount2 = 1621397855
here thread 2
Thread2 was terminated Result:nAccount1 = -1583839139, nAccount2 = 1583839139
Execution time : 312
With SetThreadAffinityMask()
:(An infinite loop occurred)
===============Peterson Algorithm================
Thread: 2 Built successfully!
here thread 2
here thread 2
here thread 2
here thread 2
Thread: 1 Built successfully!