#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
#include <mutex>
#include <chrono>
using namespace std;
struct Data
{
mutex lock;
vector<char> v;
char current = 'A';
} data;
char next(char ch)
{
switch(ch)
{
case 'A': return 'B';
case 'B': return 'C';
case 'C': return 'A';
}
}
void threadSafeOrderedPrint(char ch)
{
lock_guard<mutex> l(data.lock);
data.v.push_back(ch);
while(!data.v.empty())
{
auto it = find(begin(data.v),end(data.v),data.current);
if(it==end(data.v))
return;
cout<< *it;
data.current = next(data.current);
data.v.erase(it);
}
}
void foo(const char ch)
{
for (int i=0; i<25; ++i)
{
this_thread::sleep_for(chrono::milliseconds(10));
threadSafeOrderedPrint(ch);
}
}
int main()
{
vector<thread> threads;
threads.reserve(3);
threads.emplace_back(foo, 'A');
threads.emplace_back(foo, 'B');
threads.emplace_back(foo, 'C');
for(auto & t : threads)
t.join();
cout<<endl<<"Finished"<<endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dGhyZWFkPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8bXV0ZXg+CiNpbmNsdWRlIDxjaHJvbm8+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCnN0cnVjdCBEYXRhCnsKICBtdXRleCBsb2NrOwogIHZlY3RvcjxjaGFyPiB2OwogIGNoYXIgY3VycmVudCA9ICdBJzsKICAKfSBkYXRhOyAgCgpjaGFyIG5leHQoY2hhciBjaCkKewogICBzd2l0Y2goY2gpCQogICB7CiAgIAkgY2FzZSAnQSc6IHJldHVybiAnQic7CiAgIAkgY2FzZSAnQic6IHJldHVybiAnQyc7CiAgIAkgY2FzZSAnQyc6IHJldHVybiAnQSc7CiAgIH0KfQoKdm9pZCB0aHJlYWRTYWZlT3JkZXJlZFByaW50KGNoYXIgY2gpCnsKCWxvY2tfZ3VhcmQ8bXV0ZXg+IGwoZGF0YS5sb2NrKTsKCWRhdGEudi5wdXNoX2JhY2soY2gpOwoJd2hpbGUoIWRhdGEudi5lbXB0eSgpKQoJewoJICAgCWF1dG8gaXQgPSBmaW5kKGJlZ2luKGRhdGEudiksZW5kKGRhdGEudiksZGF0YS5jdXJyZW50KTsKCSAgIAlpZihpdD09ZW5kKGRhdGEudikpCgkgICAJICByZXR1cm47CgkgICAJICAKCSAgICBjb3V0PDwgKml0OwoJICAgIGRhdGEuY3VycmVudCA9IG5leHQoZGF0YS5jdXJyZW50KTsKCSAgICBkYXRhLnYuZXJhc2UoaXQpOwoJfQp9CgoKdm9pZCBmb28oY29uc3QgY2hhciBjaCkKewogICAgZm9yIChpbnQgaT0wOyBpPDI1OyArK2kpIAogICAgewogICAgICAgdGhpc190aHJlYWQ6OnNsZWVwX2ZvcihjaHJvbm86Om1pbGxpc2Vjb25kcygxMCkpOwogICAgICAgdGhyZWFkU2FmZU9yZGVyZWRQcmludChjaCk7CiAgICB9Cn0KIAppbnQgbWFpbigpCnsKICAgIHZlY3Rvcjx0aHJlYWQ+IHRocmVhZHM7CiAgICB0aHJlYWRzLnJlc2VydmUoMyk7CiAgICB0aHJlYWRzLmVtcGxhY2VfYmFjayhmb28sICdBJyk7CiAgICB0aHJlYWRzLmVtcGxhY2VfYmFjayhmb28sICdCJyk7CiAgICB0aHJlYWRzLmVtcGxhY2VfYmFjayhmb28sICdDJyk7CiAKICAgIGZvcihhdXRvICYgdCA6IHRocmVhZHMpIAogICAgICAgIHQuam9pbigpOwogICAgICAgIAogICAgY291dDw8ZW5kbDw8IkZpbmlzaGVkIjw8ZW5kbDsgICAgCiAKICAgIHJldHVybiAwOwp9