I am trying to control the output prints in my simulation. It prints a lot of output stream information. This is a sample code of how I try to control the output stream. Sometimes I want to print information for each thread and sometimes I do not want a single print from threads to reduce the system calls in the simulation. I pass command line argument to control the stream. Argument v means no prints. The problem is it requires a lot of if statements in whole simulator. Is there any easy way to deal with this issue?
#include <iostream>
#include <thread>
void work_to_do_1(char ch)
{
//work for thread 1
if(ch != 'v')
std::cout << "-:Thread 1:-" << std::endl;
}
void work_to_do_2(char ch)
{
if (ch != 'v')
std::cout << "-:Thread 2:-" << std::endl;
}
void work_to_do_3(char ch)
{
if (ch != 'v')
std::cout << "-:Thread 3:-" << std::endl;
}
int main(int argc, char *arg[])
{
std::cout << "You have entered " << argc
<< " arguments:" << "\n";
for (int i = 0; i < argc; ++i)
{
std::cout << arg[i] << "\n";
}
char t = *arg[1];
std::cout << "manager is running" << std::endl;
std::thread t1(work_to_do_1, t);
std::thread t2(work_to_do_2, t);
std::thread t3(work_to_do_3, t);
t1.join();
t2.join();
t3.join();
system("pause");
return 0;
}
Make your own nul stream:
struct cnul_t : std::basic_ostream<char> {} cnul;
template<class T> std::ostream& operator<<(cnul_t& os, T const&) { return os; }
And redirect your output to it to ignore it:
#include <ostream>
#include <iostream>
struct cnul_t : std::basic_ostream<char> {} cnul;
template<class T> std::ostream& operator<<(cnul_t& os, T const&) { return os; }
void maybe_log(bool b)
{
std::ostream& out = b == true ? std::cout : cnul;
out << "Hello, World!\n";
}
int main()
{
maybe_log(true); // outputs Hello, World!
maybe_log(false); // no output
}
Demo: http://coliru.stacked-crooked.com/a/362ecb660283cbff
OK, well, if you have read and understood the comments you will see that the real problem is not what you think it is. The real problem is that your logging code is not threadsafe.
This answer explains the problem very well. Although ostreams are threadsafe in themselves (since C++11), something like std::cout << "-:Thread 1:-" << std::endl; is actually two calls to std::cout.operator<< and another thread might sneak in between them thus garbling your output. This, I imagine, you could do without.
So, stealing code unashamedly from this post I humbly submit the following solution (which also has a global flag, gLogging, to turn logging on or off). This will write lines to std::cout atomically whenever you log std::endl. I wrote this as an exercise to develop my own personal skills and I thought you might like to have it.
See the linked post for an explanation of how std::endl is detected, but the underlying principle is a separate log buffer for each thread which is flushed to std::cout when it has a complete line of output to get rid of. The code includes a manager class (Logger) to take care of the details of creating, destroying and accessing these buffers. You just need to put two lines of initialisation code at the start of each thread as shown and then log to logstream rather than std::cout.
#include <iostream>
#include <sstream>
#include <mutex>
#include <map>
#include <thread>
bool gLogging = true;
constexpr int bufsize = 512; // needs to be big enough for longest logging line expected
// A streambuf that writes atomically to std::cout when (indirectly) it sees std::endl
class LogBuf : public std::stringbuf
{
public:
LogBuf () { setbuf (m_buf = new char [bufsize], bufsize); str (""); }
~LogBuf () { delete [] m_buf; }
protected:
// This gets called when the ostream we are serving sees endl
int sync() override
{
if (gLogging)
{
std::cout << str();
std::cout.flush();
}
str("");
return 0;
}
private:
char *m_buf;
};
// An ostream that uses LogBuf
class LogStream : public std::ostream
{
public:
LogStream () : std::ostream (m_LogBuf = new LogBuf ()) { }
~LogStream () { delete m_LogBuf; }
private:
LogBuf *m_LogBuf;
};
// A class to manage LogStream objects (one per thread)
class Logger
{
public:
void AddThread (void)
{
mutex.lock ();
m_logstreams [std::this_thread::get_id ()] = new LogStream ();
mutex.unlock ();
}
void RemoveThread ()
{
mutex.lock ();
std::thread::id thread_id = std::this_thread::get_id ();
LogStream *logstream = m_logstreams [thread_id];
m_logstreams.erase (m_logstreams.find (thread_id));
mutex.unlock ();
delete logstream;
}
LogStream& GetLogStream ()
{
mutex.lock ();
LogStream *logstream = m_logstreams [std::this_thread::get_id ()];
mutex.unlock ();
return *logstream;
}
private:
static std::mutex mutex;
std::map<const std::thread::id, LogStream *> m_logstreams;
};
std::mutex Logger::mutex;
Logger logger;
// A simple class to make sure we remember to call RemoveThread
class LogStreamHelper
{
public:
LogStreamHelper () { logger.AddThread (); }
~LogStreamHelper () { logger.RemoveThread (); }
inline LogStream &GetLogStream () { return logger.GetLogStream (); }
};
// Test program
void work_to_do_1()
{
LogStreamHelper logstream_helper;
LogStream& logstream = logstream_helper.GetLogStream ();
logstream << "-:Thread 1:-" << std::endl;
}
void work_to_do_2()
{
LogStreamHelper logstream_helper;
LogStream& logstream = logstream_helper.GetLogStream ();
logstream << "-:Thread 2:-" << std::endl;
}
int main ()
{
LogStreamHelper logstream_helper;
LogStream& logstream = logstream_helper.GetLogStream ();
logstream << "Main thread" << std::endl;
std::thread t1 (work_to_do_1);
std::thread t2 (work_to_do_2);
t1.join ();
t2.join ();
return 0;
}
Output:
Main thread
-:Thread 1:-
-:Thread 2:-
Run it at Wandbox.
Related
I am trying to capture the content written into std::cout stream to redirect it to a text file. For that, I intent to just follow the solution given in https://stackoverflow.com/questions/10150468/how-to-redirect-cin-and-cout-to-files:
std::ofstream out("out.txt");
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
std::cout << "blabla" << std::endl; //output to the file out.txt
I understand from https://en.cppreference.com/w/cpp/io/cout that it is safe for two threads to write at the same time in std::cout. I am fully aware it does not mean that interleaving of text may not happen. My question: is this redirection of std::cout to std::ofstream still thread safe in a multi threading context ? My understanding is that std::ofstream is not thread safe by itself.
I did a test with my own implementation of the std::streambuf injected in std::cout and 5 threads writing on std:cout:
#include <iostream>
#include <thread>
#include <atomic>
using namespace std;
class StreamToLogRedirector:public
std::streambuf
{
public:
StreamToLogRedirector ():
counter (0)
{
}
std::streamsize
xsputn (char_type const *s, std::streamsize count)
override
{
counter++;
if (counter > 1)
{
std::cerr << "Counter " << counter << std::endl;
}
counter--;
return count;
}
int
overflow (int c)
override
{
counter++;
if (counter > 1)
{
std::cerr << "Counter " << counter << std::endl;
}
counter--;
return c;
}
private:
std::atomic < int >
counter;
};
int
main ()
{
StreamToLogRedirector
redirector;
std::cout.rdbuf (&redirector);
auto
a = std::thread ([](){
while (true) std::cout << "Write from A\n";}
);
auto
b = std::thread ([](){
while (true) std::cout << "Write from B\n";}
);
auto
c = std::thread ([](){
while (true) std::cout << "Write from C\n";}
);
auto
d = std::thread ([](){
while (true) std::cout << "Write from D\n";}
);
auto
e = std::thread ([](){
while (true) std::cout << "Write from E\n";}
);
a.join ();
b.join ();
c.join ();
d.join ();
e.join ();
return 0;
}
I can see that the counter is reaching 5, meaning that the functions StreamToLogRedirector are called in parallel.
My conclusion is that the thread safety aspect is not handled at the level of the std::cout object std::ostream, but at the level of the underlying std::streambuf. If std::ofstream is not thread safe, that mean that redirecting std::cout to std::ofstream is now making the usage of std:cout not thread safe by itself.
Is my conclusion correct or I am missing something ?
Thank you,
Simon
This is my minimal, reproducible example
#include <memory>
#include <chrono>
#include <thread>
#include <iostream>
#include <functional>
class BaseClass {
public:
void do_func() {
while(true) {
std::cout << "doing stuff" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
auto obj = std::make_unique<BaseClass>();
std::thread t(&BaseClass::do_func, obj.get());
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "reset called!" << std::endl;
obj.reset();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "going out of scope" << std::endl;
t.join();
return 0;
}
I was expecting the object to be deleted after reset is called. Even the code cannot exit because the while loop is blocking, which is understandable. I need to delete the object after a particular event, and cannot wait till the unique_ptr goes out of scope. If I change the do_func to
void do_func() {
std::cout << "doing stuff" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(20));
}
then it is the expected behaviour.
Edit:
Based on your comments I have updated my code to
#include <memory>
#include <chrono>
#include <thread>
#include <iostream>
#include <functional>
class BaseClass {
public:
BaseClass() : x(1) {
dummy = std::make_shared<SomeClass>();
}
void do_func() {
while(true) {
std::cout << "doing stuff " << dummy->do_stuff(x) << std::endl;
x++;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
private:
int x;
class SomeClass {
public:
int do_stuff(int x) {
return x * x;
}
};
std::shared_ptr<SomeClass> dummy;
};
int main() {
auto obj = std::make_unique<BaseClass>();
std::thread t(&BaseClass::do_func, obj.get());
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "reset called!" << std::endl;
obj.reset();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "going out of scope" << std::endl;
t.join();
return 0;
}
And now the function does print garbage values. Does that mean I need to explicitly delete dummy in the destructor?
The simplest way to synchronize these two threads would be to use std::atomic_bool
#include <atomic>
class BaseClass {
public:
std::atomic_bool shouldContinueWork = true;
void do_func() {
while(shouldContinueWork) {
std::cout << "doing stuff" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
auto obj = std::make_unique<BaseClass>();
std::thread t(&BaseClass::do_func, obj.get());
std::this_thread::sleep_for(std::chrono::seconds(5));
obj->shouldContinueWork = false; //the thread will not do anything more after this, but the sleep will need to end on it's own
std::cout << "stopping work!" << std::endl;
// do not remove the object before join is called - you don't know if it will be still accessed from the other thread or not
// obj.reset();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "going out of scope" << std::endl;
t.join();
// here it is safe to remove the `obj`, main thread is surely the only thread that accesses it
// (but it goes out of scope anyway)
return 0;
}
This solution doesn't take into account stopping the work midway (i.e. whole loop iteration must always be performed) and is generally prone to having a few more or less iterations of work - it should be precise enough when you have sleep of 1s, but with smaller sleep it won't guarantee any exact number of iterations, take that into account. std::condition_variable can be used for more precise control of thread synchronization.
Thanks for all your quick responses! Let me know if this is a good solution
#include <memory>
#include <chrono>
#include <thread>
#include <iostream>
#include <functional>
class BaseClass {
public:
BaseClass() : x(1) {
dummy = std::make_shared<SomeClass>();
}
virtual ~BaseClass() {
dummy.reset();
}
void do_func() {
while(dummy) {
std::cout << "doing stuff " << dummy->do_stuff(x) << std::endl;
x++;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
private:
int x;
class SomeClass {
public:
int do_stuff(int x) {
return x * x;
}
};
std::shared_ptr<SomeClass> dummy;
};
class DerivedClass : public BaseClass {
};
int main() {
auto obj = std::make_unique<DerivedClass>();
std::thread t(&BaseClass::do_func, obj.get());
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "reset called!" << std::endl;
obj.reset();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "going out of scope" << std::endl;
t.join();
return 0;
}
The behaviour is now as expected.
I'm using Boost::thread to implement an InterruptibleThread class, while getting segmentation fault during execution. Any idea?
The source and the output are under below.
interruptiblethread.h
#ifndef INTERRUPTIBLETHREAD_H
#define INTERRUPTIBLETHREAD_H
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/tss.hpp>
class InterruptFlag
{
public:
inline void set()
{
boost::lock_guard<boost::mutex> guard(_mtx);
_set = true;
}
inline bool is_set()
{
std::cout << "is_set()" << std::endl;
boost::lock_guard<boost::mutex> guard(_mtx);
std::cout << "is_set() end" << std::endl;
return _set;
}
private:
boost::mutex _mtx;
bool _set;
};
extern boost::thread_specific_ptr<InterruptFlag> this_thread_interrupt_flag;
class InterruptibleThread
{
public:
template<typename FunctionType>
InterruptibleThread(FunctionType f)
{
boost::promise<InterruptFlag*> p;
_internal_thread = boost::thread([f, &p]()
{
p.set_value(this_thread_interrupt_flag.get());
f();
});
_interrupt_flag = p.get_future().get();
}
inline void interrupt()
{
if (_interrupt_flag != nullptr)
{
_interrupt_flag->set();
}
}
private:
boost::thread _internal_thread;
InterruptFlag* _interrupt_flag;
};
#endif // INTERRUPTIBLETHREAD_H
interruptiblethread.cpp
#include <iostream>
#include <functional>
#include "interruptiblethread.h"
using std::cout; using std::endl;
using std::function;
boost::thread_specific_ptr<InterruptFlag> this_thread_interrupt_flag;
struct thread_interrupted {};
void interruption_point()
{
cout << "interruption_point()" << endl;
if (this_thread_interrupt_flag->is_set())
{
cout << "is_set" << endl;
throw thread_interrupted();
}
}
void foo()
{
while (true)
{
cout << "iterate" << endl;
try
{
interruption_point();
} catch (const thread_interrupted& interrupt)
{
cout << "catch thread_interrupted" << endl;
break;
}
}
}
int main()
{
InterruptibleThread int_thread(foo);
int_thread.interrupt();
while (true) {}
}
Output:
➜ build ./main
iterate
interruption_point()
is_set()
[1] 44435 segmentation fault ./main
this_thread_interrupt_flag is not initialized. Please initialize it correctly as described here
Your call to is_set is UB.
I'm trying to use the boost thread library. Below is a sample code.
For some reason I'm not seeing any output.
int main()
{
myclass Class1;
while(1) {
}
}
/************************************/
typedef boost::shared_ptr<boost::thread> thread_ptr;
// class definition
myclass::myclass()
{
// thread_ptr is of type thread_ptr
threat_ptr1 = thread_ptr(new boost::thread(&myclass::function_name, this));
}
void myclass:function_name()
{
std::cout << "enter here";
while( true ) {
boost::this_thread::sleep(boost::posix_time::seconds(2));
// do some stuff
}
}
Instead of
std::cout << "enter here";
use
std::cout << "enter here" << std::endl;
Flushing is your friend ;-)
As a sidenote, in production you should not use while(1){} instead of join(). What a waste of CPU time.
I am playing around with some sockets, thread and mutexes. My question concerns threads and mutexes:
int ConnectionHandler::addNewSocket(){
this->connectionList_mutex.lock();
std::cout << "test1" << std::endl;
this->connectionList_mutex.unlock();
return 0;
}
int ConnectionHandler::main(){
while(true){
this->connectionList_mutex.lock();
std::cout << "test2" << std::endl;
this->connectionList_mutex.unlock();
}
}`
The main function is running in one thread, while the addNewSocket is called by another thread. The problem is, that when addNewSocket is called once (by the second thread), the next unlock by thread 1 (main) will fail with a strange "signal SIGABRT". I have worked two days on this now, but i did not manage to get it fixed, sadly. I hope you can help me.
Edit: ConnectionHandler is a class, that has connectionList_mutex as a member.
Edit: Sometimes i also get this error: "Assertion failed: (ec == 0), function unlock, file /SourceCache/libcxx/libcxx-65.1/src/mutex.cpp, line 44." but it occurs randomly.
Edit: This is the whole class (Reduced to a minimum, should be context independant to a certain degree, but crashes when i put it right after a client connected, and works if i put it right after the start:
class ConnectionHandler{
public:
ConnectionHandler();
int addNewSocket();
private:
int main();
static void start(void * pThis);
std::mutex connectionList_mutex;
};
ConnectionHandler::ConnectionHandler(){
std::thread t(&this->start, this);
t.detach();
}
void ConnectionHandler::start(void * pThis){
ConnectionHandler *handlerThis;
handlerThis = (ConnectionHandler *)pThis;
handlerThis->main();
}
int ConnectionHandler::addNewSocket(){
this->connectionList_mutex.lock();
std::cout << "test1" << std::endl;
this->connectionList_mutex.unlock();
return 0;
}
int ConnectionHandler::main(){
while(true){
this->connectionList_mutex.lock();
std::cout << "test2" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
this->connectionList_mutex.unlock();
}
}
My guess is that your ConnectionHandler object is being destroyed somewhere. Also, you have defined ConnectionHandler::start in a silly way.
First, ConnectionHandler::start should be defined this way:
void ConnectionHandler::start(ConnectionHandler * pThis){
pThis->main();
}
The C++11 ::std::thread class is perfectly capable of preserving the type of the function argument so there is no need to resort to void *.
Secondly, add in this code:
void ConnectionHandler::~ConnectionHandler(){
const void * const meptr = this;
this->connectionList_mutex.lock();
::std::cout << "ConnectionHandler being destroyed at " << meptr << ::std::endl;
this->connectionList_mutex.unlock();
}
And change the constructor to read:
ConnectionHandler::ConnectionHandler(){
const void * const meptr = this;
::std::cout << "ConnectionHandler being created at " << meptr << ::std::endl;
std::thread t(&this->start, this);
t.detach();
}
This will show you when the ConnectionHandler object is being destroyed. And my guess is that your code is destroying it while your detached thread is still running.
The meptr thing is because operator << has an overload for void * that prints out the pointer value. Printing out the pointer value for this will allow you to match up calls to the constructor and destructor if you're creating multiple ConnectionHandler objects.
Edit: Since it turned out I was correct, here is how I would recommend you write the play ConnectionHandler class:
#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>
#include <mutex>
class ConnectionHandler {
public:
ConnectionHandler();
~ConnectionHandler();
ConnectionHandler(const ConnectionHandler &) = delete;
const ConnectionHandler &operator =(const ConnectionHandler &) = delete;
int addNewSocket();
private:
int main();
static void start(ConnectionHandler * pThis);
::std::mutex connectionList_mutex;
volatile ::std::atomic_bool thread_shutdown;
::std::thread thread;
};
ConnectionHandler::ConnectionHandler()
: thread_shutdown(false), thread(&this->start, this)
{
}
ConnectionHandler::~ConnectionHandler()
{
thread_shutdown.store(true);
thread.join();
}
void ConnectionHandler::start(ConnectionHandler * pThis){
pThis->main();
}
int ConnectionHandler::addNewSocket(){
::std::lock_guard< ::std::mutex> lock(connectionList_mutex);
::std::cout << "test1" << ::std::endl;
return 0;
}
int ConnectionHandler::main(){
while(!thread_shutdown.load()){
::std::lock_guard< ::std::mutex> lock(connectionList_mutex);
::std::cout << "test2" << ::std::endl;
::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
}
return 0;
}