When interviewing for a job in the past, I was asked the following question:
Write a multithreaded program that prints a sequence of characters like this: A, B, A, B, A, B… Synchronize properly so it never prints the same character more than once in a row.
Thinking quickly on my feet 🙂 I realized the trick is to use an event object (I will be using this one). But wait, one event object is not enough. The real trick is to use two event objects! Where thread 1 waits on event 1 to be signaled, then prints ‘A’, and finally signals event 2; and repeats the sequence in a loop. Thread 2 waits on event 2, then prints ‘B’, and finally signals event 1. Ditto loop. That should do it!
The answer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <iostream> #include <mutex> #include <thread> #include "event.h" using namespace std; mutex cout_lock; #define trace(x) { scoped_lock<mutex> lock(cout_lock); cout << x << endl; } const int COUNT = 3; int main(int argc, char** argv) { auto_event e1, e2; thread t1([&](){ for(int i = 0; i < COUNT; ++i) { e1.wait(); trace("A"); e2.signal(); } }); thread t2([&](){ for(int i = 0; i < COUNT; ++i) { e2.wait(); trace("B"); e1.signal(); } }); e1.signal(); t1.join(); t2.join(); return 1; } |
A
Program output.
B
A
B
A
B
Thanks for your interview question series
How do you compile this one?
go to my GitHub repository and get the event.h file
Hmm, it does not say which thread should print what…
A multithreaded program has at least two threads, right?
The following should work:
void print()
{
for (;;)
{
std::cout << ‘A’ << std::endl;
std::cout << ‘B’ << std::endl;
}
}
int main()
{
std::thread t1(print);
t1.join();
return 0;
}
// 😀