2

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!
Lin
  • 31
  • 3
  • Read [this](https://stackoverflow.com/questions/5919699/proper-usage-of-setthreadaffinitymask) – ntshetty Apr 12 '18 at 09:43
  • Welcome to Stack Overflow. This is a very good question, and much better than the vast majority of new posters' material. To go with my edit, my minor pieces of advice are: (a) trim out chatty material, aim for technical writing if you can, (b) use `inline formatting for code` where appropriate, and (c) break large paragraphs down into smaller ones that are easier to read. But these are minor things, good work! – halfer Apr 12 '18 at 09:54
  • Also, since your images are of console output, they would generally be best as text - you can paste from your console and just apply block code formatting. – halfer Apr 12 '18 at 09:57
  • 1
    Thank you for your advises sincerely! I'll be more careful next time! It's very kind of you! I'm still working on this problem – Lin Apr 12 '18 at 10:47
  • I've just figure out the answer to my question myself by adding some notification in my loops, but due to the reputation setting I'm going to gain 4 more reputation so that I can answer my own question as soon as possible ! Thank you all !! – Lin Apr 13 '18 at 12:08
  • Excellent, pleased you fixed it `:=)` – halfer Apr 14 '18 at 02:06

0 Answers0