Reputation: 15538
I was wondering how I could handle printing when using multiple threads.
I thought it would be pretty simple:
#include <iostream>
#include <pthread.h>
using namespace std;
bool printing = false;
struct argumentStruct {
int a;
float b;
};
void *ThreadFunction(void *arguments) {
struct argumentStruct*args = (struct argumentStruct*)arguments;
int a = args->a;
float b = args->b;
while (printing) {}
printing = true;
cout << "Some text...." << a << b << endl;
printing = false;
}
main() {
pthread_t threads[3];
struct argumentStruct argStruct[3];
argStruct[0].a = 1;
argStruct[0].b = 1.1;
pthread_create(&threads[0], NULL, &ThreadFunction, (void *)&argStruct[0]);
argStruct[1].a = 2;
argStruct[1].b = 2.2;
pthread_create(&threads[1], NULL, &ThreadFunction, (void *)&argStruct[1]);
argStruct[2]a = 3;
argStruct[2].b = 3.3;
pthread_create(&threads[2], NULL, &ThreadFunction, (void *)&argStruct[2]);
getchar();
return 0;
}
But this doesn't really work that well. Some couts are just skipped (or maybe overwritten?).
So what am I doing wrong? How can I handle this properly?
Upvotes: 0
Views: 1999
Reputation: 5416
The problem is that the statements that test and set the printing
variable are not atomic, i.e., they don't execute without being interrupted by the OS scheduler which switches the CPU among threads. You should use mutexes in order to stop other threads while printing. Here you have a nice example:
Upvotes: 2
Reputation: 409442
You have a race condition, where two (or more) threads can both set printing
to true
.
This is because assignment is not an atomic operation, it's done in multiple steps by the CPU, and if the thread is interrupted before the actual setting of the variable to true
, and another thread starts running, then you can have two threads running simultaneously both believing the variable is true
. For more clarity:
printing
is false
printing
is false
printing
to true
printing
to true
Now both thread A and B are running full speed ahead.
That's why there are threading primitives such as semaphores and mutex that handle these things.
Upvotes: 1