RazaUsman_k RazaUsman_k - 24 days ago 6
C++ Question

Multi Threading gives some weird results

I just used Multi threading. It works but it gives some weird results and every time i run the program the results are different.Can anyone tell me what i am doing wrong

Now in my output i'm supposed to have 2 blocks which continuously move up and down but in actual output some other blocks appear out of nowhere you can see my output in the link

(i.e i excluded the global char array from the main code i am adding another code section so you can run my code and help me )

Main Code

#include<iostream> //libraries
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<thread>

using namespace std;

void print();
void gotoxy(int,int);
int race();
void block1();
void block2();

COORD coord={0,0};//global variable
char road[22][80]={//haven't mentioned the array }; //global char array

void main()
{
race();
}

int race()
{
char swap;

//printing the array once
cout<<endl;
for(int i=0 ; i<22 ; i++)
{
for(int j=0 ; j<80 ; j++)
{
cout<<road[i][j];
}
}

thread t1 (block2);
thread t2 (block1);

t1.join();
t2.join();

getch();
return 0;
}

void block1() //definition of block1
{
char swap;
int i=1 , j=4;
while(!kbhit())
{
while(road[i+1][j]!='\xdb')
{
swap=road[i][j];
road[i][j]=road[i+1][j];
road[i+1][j]=swap;
gotoxy(4,i+1);
cout<<road[i][j];
gotoxy(4,i+2);
cout<<road[i+1][j];
Sleep(200);
i++;
}

if(road[i+1][j]=='\xdb')

while(road[i-1][j]!='\xdb')
{
swap=road[i][j];
road[i][j]=road[i-1][j];
road[i-1][j]=swap;
gotoxy(4,i);
cout<<road[i-1][j];
gotoxy(4,i+1);
cout<<road[i][j];
Sleep(500);
i--;
}

}
}

void block2() //definition of function block2
{
char swap;
int i=1 , j=7;
while(!kbhit())
{
while(road[i+1][j]!='\xdb')
{
swap=road[i][j];
road[i][j]=road[i+1][j];
road[i+1][j]=swap;
gotoxy(7,i+1);
cout<<road[i][j];
gotoxy(7,i+2);
cout<<road[i+1][j];
Sleep(50);
i++;
}

if(road[i+1][j]=='\xdb')

while(road[i-1][j]!='\xdb')
{
swap=road[i][j];
road[i][j]=road[i-1][j];
road[i-1][j]=swap;
gotoxy(7,i);
cout<<road[i-1][j];
gotoxy(7,i+1);
cout<<road[i][j];
Sleep(50);
i--;
}

}
}


Global Char Array

char road[22][80]={ //global char array
'\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb',
'\xdb','.','.','.','\xdb','.','.','\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb',1,'.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','\xdb',
'\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb','\xdb',


};

Answer

You have a race condition when you are outputting to the screen. For example, if thread one is running

        gotoxy(4,i+1);
        cout<<road[i][j];

and execution switches to thread 2 after the gotoxy(4,i+1);. Thread 2 then does its own

        gotoxy(7,i+1);
        cout<<road[i][j];

The location of the output cursor will now be (8, i+1). Then when thread 1 gets to run again, it will use cout<<road[i][j]; which will output to the current cursor, which is in the incorrect place.

To fix this, you would have to use race protection mechanisms, as πάντα ῥεῖ said. Something like a mutex would work.