#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <iostream>
#include <queue>
class Logger // singleton class
{
public :
Logger( ) : mThread{ } , mCV{ } , mMutex{ } , mQueue{ } , mStop{ false }
{
mThread = std:: thread ( & Logger:: Run , this ) ;
}
~Logger( )
{
if ( mThread.joinable ( ) )
{
mThread.join ( ) ;
}
}
static Logger& getInstance( ) {
static Logger logger;
return logger;
}
void Stop( )
{
{
std:: lock_guard < std:: mutex > lk( mMutex) ;
mStop = true ;
}
mCV.notify_one ( ) ;
}
void WriteMessage( const std:: string & msg)
{
{
std:: lock_guard < std:: mutex > lk( mMutex) ;
mQueue.push ( msg) ;
}
mCV.notify_one ( ) ;
}
private :
void Run( )
{
while ( true )
{
std:: unique_lock < std:: mutex > lock( mMutex) ;
mCV.wait ( lock, [ & ] ( ) { return mStop || ! mQueue.empty ( ) ; } ) ;
//Stop if needed
if ( mStop)
{
std:: cout << "--- Stopping ---" << std:: endl ;
break ;
}
std:: string msg = std:: move ( mQueue.front ( ) ) ;
mQueue.pop ( ) ;
lock.unlock ( ) ;
std:: cout << msg << std:: endl ;
}
}
private :
std:: thread mThread;
std:: condition_variable mCV;
std:: mutex mMutex;
std:: queue < std:: string > mQueue;
bool mStop;
} ;
int main( )
{
Logger& logger = Logger:: getInstance ( ) ;
std:: thread t1( [ & logger, count = 10 ] ( ) mutable {
while ( count > 0 )
{
logger.WriteMessage ( "Hello from thread1" ) ;
std:: this_thread :: sleep_for ( std:: chrono :: milliseconds ( 500 ) ) ;
-- count;
}
} ) ;
std:: thread t2( [ & logger, count = 20 ] ( ) mutable {
while ( count > 0 )
{
logger.WriteMessage ( " Hello from thread2" ) ;
std:: this_thread :: sleep_for ( std:: chrono :: milliseconds ( 250 ) ) ;
-- count;
}
} ) ;
t1.join ( ) ;
t2.join ( ) ;
logger.Stop ( ) ;
}
I2luY2x1ZGUgPHRocmVhZD4KI2luY2x1ZGUgPG11dGV4PgojaW5jbHVkZSA8Y29uZGl0aW9uX3ZhcmlhYmxlPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxxdWV1ZT4KIApjbGFzcyBMb2dnZXIgLy8gc2luZ2xldG9uIGNsYXNzCnsKcHVibGljOgoJTG9nZ2VyKCkgOiBtVGhyZWFke30sIG1DVnt9LCBtTXV0ZXh7fSwgbVF1ZXVle30sIG1TdG9weyBmYWxzZSB9Cgl7CgkJbVRocmVhZCA9IHN0ZDo6dGhyZWFkKCZMb2dnZXI6OlJ1biwgdGhpcyk7Cgl9CiAKCX5Mb2dnZXIoKQoJewoJCWlmIChtVGhyZWFkLmpvaW5hYmxlKCkpCgkJewoJCQltVGhyZWFkLmpvaW4oKTsKCQl9Cgl9CiAKCXN0YXRpYyBMb2dnZXImIGdldEluc3RhbmNlKCkgewoJCXN0YXRpYyBMb2dnZXIgbG9nZ2VyOwoJCXJldHVybiBsb2dnZXI7Cgl9CiAKCXZvaWQgU3RvcCgpCgl7CgkJewoJCSAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbGsobU11dGV4KTsKCQkgICAgbVN0b3AgPSB0cnVlOwoJCX0KCQltQ1Yubm90aWZ5X29uZSgpOwoJfQogCgl2b2lkIFdyaXRlTWVzc2FnZShjb25zdCBzdGQ6OnN0cmluZyYgbXNnKQoJewoJCXsKCQkgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxrKG1NdXRleCk7CgkJICAgIG1RdWV1ZS5wdXNoKG1zZyk7CgkJfQoJCW1DVi5ub3RpZnlfb25lKCk7Cgl9CiAKcHJpdmF0ZToKCXZvaWQgUnVuKCkKCXsKCQl3aGlsZSAodHJ1ZSkKCQl7CgkJCXN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtTXV0ZXgpOwoJCQltQ1Yud2FpdChsb2NrLCBbJl0oKSB7IHJldHVybiBtU3RvcCB8fCAhbVF1ZXVlLmVtcHR5KCk7IH0pOwogCgkJCS8vU3RvcCBpZiBuZWVkZWQKCQkJaWYgKG1TdG9wKQoJCQl7CgkJCQlzdGQ6OmNvdXQgPDwgIi0tLSBTdG9wcGluZyAtLS0iIDw8IHN0ZDo6ZW5kbDsKCQkJCWJyZWFrOwoJCQl9CiAKCQkJc3RkOjpzdHJpbmcgbXNnID0gc3RkOjptb3ZlKG1RdWV1ZS5mcm9udCgpKTsKCQkJbVF1ZXVlLnBvcCgpOwoJCQlsb2NrLnVubG9jaygpOwogCgkJCXN0ZDo6Y291dCA8PCBtc2cgPDwgc3RkOjplbmRsOwoJCX0KCX0KIApwcml2YXRlOgoJc3RkOjp0aHJlYWQgbVRocmVhZDsKCXN0ZDo6Y29uZGl0aW9uX3ZhcmlhYmxlIG1DVjsKCXN0ZDo6bXV0ZXggbU11dGV4OwoJc3RkOjpxdWV1ZTxzdGQ6OnN0cmluZz4gbVF1ZXVlOwoJYm9vbCBtU3RvcDsKfTsKIAogCmludCBtYWluKCkKewogICAgTG9nZ2VyJiBsb2dnZXIgPSBMb2dnZXI6OmdldEluc3RhbmNlKCk7CiAKICAgIHN0ZDo6dGhyZWFkIHQxKFsmbG9nZ2VyLCBjb3VudCA9IDEwXSgpIG11dGFibGUgewogICAgICAgIHdoaWxlIChjb3VudCA+IDApCiAgICAgICAgewogICAgICAgICAgICBsb2dnZXIuV3JpdGVNZXNzYWdlKCJIZWxsbyBmcm9tIHRocmVhZDEiKTsKICAgICAgICAgICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMoNTAwKSk7CiAgICAgICAgICAgIC0tY291bnQ7CiAgICAgICAgfQogICAgfSk7CiAKICAgIHN0ZDo6dGhyZWFkIHQyKFsmbG9nZ2VyLCBjb3VudCA9IDIwXSgpIG11dGFibGUgewogICAgICAgIHdoaWxlIChjb3VudCA+IDApCiAgICAgICAgewogICAgICAgICAgICBsb2dnZXIuV3JpdGVNZXNzYWdlKCIgICAgICAgIEhlbGxvIGZyb20gdGhyZWFkMiIpOwogICAgICAgICAgICBzdGQ6OnRoaXNfdGhyZWFkOjpzbGVlcF9mb3Ioc3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcygyNTApKTsKICAgICAgICAgICAgLS1jb3VudDsKICAgICAgICB9CiAgICB9KTsKIAogICAgdDEuam9pbigpOwogICAgdDIuam9pbigpOwogICAgbG9nZ2VyLlN0b3AoKTsKIAp9