Threads

Hi guys, I'm having a problem using threads. When I run the functions individually (one per time) they work perfectly, but when I set them to run together (at the same time) many bugs start to appear.
The main problem is with the positions, since the "math" part (operations and so on) work fine. But the positions in the console go crazy.
I created a simple program to try them: it makes 2 squares move in the screen.
Could anyone explain it to me/help me to solve it/indicate another function for parallel programming?
Thank you very much.
The code follows below:

#include <iostream>
#include <Windows.h>
#include <thread>

using namespace std;

void curPos(int x, int y)
{
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
csbiInfo.dwCursorPosition.X = x;
csbiInfo.dwCursorPosition.Y = y;
SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition);
}

void square1()
{
int i;
int j;
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);

for (i = 1; i <= 19; ++i)
{
SetConsoleTextAttribute(h, BACKGROUND_BLUE | BACKGROUND_INTENSITY);
curPos(i + 1, 20);
cout << " ";
Sleep(300);
SetConsoleTextAttribute(h, 0);
curPos(i + 1, 20);
cout << " ";
}
}

void square2()
{
int i;
int j;
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);

for (j = 1; j <= 19; ++j)
{
SetConsoleTextAttribute(h, BACKGROUND_BLUE | BACKGROUND_INTENSITY);
curPos(20, 20 - j + 1);
cout << " ";
Sleep(300);
SetConsoleTextAttribute(h, 0);
curPos(20, 20 - j + 1);
cout << " ";
}
}

int main()
{
thread first (square1);
thread second(square2);

first.join();
second.join();

return 0;
}
You're not doing any synchronization, so of course this is going to fail spectacularly.

Threads run simultaneously, but share memory space. This means that when you change something in one thread, it changes in all threads.

In your code, you have two threads that are wrestling with the console. But you have to remember that both are using the same console at the same time.

Simply, you have these actions being done:

- Square1 set position
- Square1 draw
- Square2 set position
- Square2 draw


But these threads run simultaneously, so the order in which the thread does its work is not guaranteed. So they might execute like this:

- Square2 set position
- Square1 set position
- Square1 draw
- Square2 draw

Which will result in Square2 being drawn in completely the wrong position, because the other thread moved the position.


On top of this, there are more complex issues called "race conditions". What happens if Square1 and Square2 are being drawn at exactly the same time? Which one (if any) gets drawn?


This is an extremely complex problem -- and it makes multithreading in C++ actually pretty difficult. You can't just slap threads in your program and expect it to work -- you have to be extremely careful about how all threads interact with each other.



To avoid race conditions, any time you share data between multiple threads, that data MUST be guarded so that only one thread is accessing it at a time. This is usually done with mutexes or atomic variables. I suggest you read up on how those work before continuing with threading -- you simply cannot write a multithreaded program in C++ without them.
Topic archived. No new replies allowed.