#include <iostream>
#include <iomanip>
#include <thread>
#include <atomic>
#include <mutex>
using namespace std;
mutex out;
class Thread
{
public :
template < class Fn, class ... Args >
Thread( Fn&& Fx, Args&& ... Ax ) :
run( forward< Fn> ( Fx) , forward< Args> ( Ax) ...)
,check( [ this ] ( ) { this- > run.join ( ) ; this- > isDone = true ; } )
,isDone( false )
{
}
~Thread( ) { check.join ( ) ; }
private :
thread run, check;
public :
atomic< bool > isDone;
} ;
void doit( const char * s, int n)
{
for ( int i = 0 ; i < n; ++ i)
{
{
lock_guard< mutex> lock( out) ;
cout << s << endl;
}
this_thread:: sleep_for ( 10ms) ;
}
}
int main( int argc, char * argv[ ] )
{
try {
Thread t( doit,"Hello" ,10 ) ;
Thread g( doit,"Dolly" ,20 ) ;
for ( int i = 0 ; i < 100 ; ++ i)
{
this_thread:: sleep_for ( 10ms) ;
{
int count = 0 ;
lock_guard< mutex> lock( out) ;
if ( t.isDone ) { cout << "t done\n " ; ++ count; }
if ( g.isDone ) { cout << "g done\n " ; ++ count; }
if ( count == 2 ) break ;
}
}
} catch ( ...) { cerr << "Exception!\n " ; }
cout << "Done!\n " ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHRocmVhZD4KI2luY2x1ZGUgPGF0b21pYz4KI2luY2x1ZGUgPG11dGV4PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCm11dGV4IG91dDsKCmNsYXNzIFRocmVhZAp7CgpwdWJsaWM6CiAgICB0ZW1wbGF0ZTxjbGFzcyBGbiwgY2xhc3MuLi4gQXJncz4KICAgIFRocmVhZChGbiYmIEZ4LCBBcmdzJiYuLi4gQXgpOgogICAgcnVuKGZvcndhcmQ8Rm4+KEZ4KSwgZm9yd2FyZDxBcmdzPihBeCkuLi4pCiAgICAsY2hlY2soW3RoaXNdKCl7IHRoaXMtPnJ1bi5qb2luKCk7IHRoaXMtPmlzRG9uZSA9IHRydWU7IH0pCiAgICAsaXNEb25lKGZhbHNlKQogICAgewogICAgfQogICAgflRocmVhZCgpeyBjaGVjay5qb2luKCk7IH0KcHJpdmF0ZToKICAgIHRocmVhZCBydW4sIGNoZWNrOwpwdWJsaWM6CiAgICBhdG9taWM8Ym9vbD4gaXNEb25lOwp9OwoKdm9pZCBkb2l0KGNvbnN0IGNoYXIgKiBzLCBpbnQgbikKewogICAgZm9yKGludCBpID0gMDsgaSA8IG47ICsraSkKICAgIHsKICAgICAgICB7CiAgICAgICAgICAgIGxvY2tfZ3VhcmQ8bXV0ZXg+IGxvY2sob3V0KTsKICAgICAgICAgICAgY291dCA8PCBzIDw8IGVuZGw7CiAgICAgICAgfQogICAgICAgIHRoaXNfdGhyZWFkOjpzbGVlcF9mb3IoMTBtcyk7CiAgICB9Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyICogYXJndltdKQp7CiAgICB0cnkgewogICAgICAgIFRocmVhZCB0KGRvaXQsIkhlbGxvIiwxMCk7CiAgICAgICAgVGhyZWFkIGcoZG9pdCwiRG9sbHkiLDIwKTsKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgMTAwOyArK2kpCiAgICAgICAgewogICAgICAgICAgICB0aGlzX3RocmVhZDo6c2xlZXBfZm9yKDEwbXMpOwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICAgICAgbG9ja19ndWFyZDxtdXRleD4gbG9jayhvdXQpOwoKICAgICAgICAgICAgICAgIGlmICh0LmlzRG9uZSkgeyBjb3V0IDw8ICJ0IGRvbmVcbiI7ICsrY291bnQ7IH0KICAgICAgICAgICAgICAgIGlmIChnLmlzRG9uZSkgeyBjb3V0IDw8ICJnIGRvbmVcbiI7ICsrY291bnQ7IH0KICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSAyKSBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gY2F0Y2goLi4uKSB7IGNlcnIgPDwgIkV4Y2VwdGlvbiFcbiI7IH0KICAgIGNvdXQgPDwgIkRvbmUhXG4iOwp9