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.
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 question already has answers here:
How do I terminate a thread in C++11?
(7 answers)
How to stop the thread execution in C++
(3 answers)
Proper way to terminate a thread in c++
(1 answer)
Closed 3 years ago.
My main function loads a monitoring class. This class calls external services to periodically get some data and report health status.
These are the task_1 and task_2 in the class below, that can have sub tasks. The tasks accumulate some values that are stored to a shared "Data" class.
So each task_N is coupled with a thread that executes, sleeps for a while and does this forever until the program stops.
My basic problem is that I cannot stop the threads in the Monitor class, since they might be waiting for the timer to expire (sleep)
#include <iostream>
#include <thread>
#include <utility>
#include "Settings.hpp"
#include "Data.hpp"
class Monitors {
public:
Monitors(uint32_t timeout1, uint32_t timeout2, Settings settings, std::shared_ptr<Data> data)
: timeout_1(timeout1), timeout_2(timeout2), settings_(std::move(settings)), data_(std::move(data)) {}
void start() {
thread_1 = std::thread(&Monitors::task_1, this);
thread_2 = std::thread(&Monitors::task_2, this);
started_ = true;
}
void stop() {
started_ = false;
thread_1.join();
thread_2.join();
std::cout << "stopping threads" << std::endl;
}
virtual ~Monitors() {
std::cout << "Monitor stops" << std::endl;
}
private:
void subtask_1_1() {
//std::cout << "subtask_1_1 reads " << settings_.getWeb1() << std::endl;
}
void subtask_1_2() {
//std::cout << "subtask_1_2" << std::endl;
data_->setValue1(21);
}
void task_1() {
while(started_) {
subtask_1_1();
subtask_1_2();
std::this_thread::sleep_for(std::chrono::milliseconds(timeout_1));
std::cout << "task1 done" << std::endl;
}
}
void subtask_2_1() {
//std::cout << "subtask_2_1" << std::endl;
}
void subtask_2_2() {
//std::cout << "subtask_2_2" << std::endl;
}
void task_2() {
while(started_) {
subtask_2_1();
subtask_2_2();
std::this_thread::sleep_for(std::chrono::milliseconds(timeout_2));
std::cout << "task2 done" << std::endl;
}
}
private:
bool started_ {false};
std::thread thread_1;
std::thread thread_2;
uint32_t timeout_1;
uint32_t timeout_2;
Settings settings_;
std::shared_ptr<Data> data_;
};
The main function is here:
auto data = std::make_shared<Data>(10,20);
Settings set("hello", "world");
Monitors mon(1000, 24000,set,data);
mon.start();
int count = 1;
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << data->getValue2() << " and count is " << count << std::endl;
count++;
if ( count == 10)
break;
}
std::cout << "now I am here" << std::endl;
mon.stop();
return 0;
Now when I call mon.stop() the main thread stops only when the timer exprires.
How can I gracefully call mon.stop() and interrupt and call the task_N?
UPDATE: Since I don't want to call std::terminate, which is the proper way to implement a monitor class in c++
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.
I am making bigger program where I want to use threads so as first I am trying to find out how threads actually work so I created a simple program and I can not understand why I do not get a message "Bomberman has just put a bomb. Wait for the boom." earlier than "The bomb has just detonated.".
Can anyone instruct me why is it not working as I expect?
#include <unistd.h>
#include <chrono>
#include <iostream>
#include <thread>
using namespace std;
class CBomberman;
class CBomb {
public:
CBomb(void) : m_Owner(nullptr) {
thread other_thread(&CBomb::Timer, this);
other_thread.join();
}
private:
void Timer(void) {
this_thread::sleep_for(chrono::seconds(3));
cout << "The bomb has just detonated." << endl;
}
CBomberman* m_Owner;
};
class CBomberman {
public:
CBomberman(void) : m_Bomb(nullptr) {}
bool PutBomb(void) {
if (m_Bomb == nullptr) {
m_Bomb = new CBomb();
delete m_Bomb;
return true;
} else {
cout << "The bomb has already been put." << endl;
return false;
}
}
private:
CBomb* m_Bomb;
};
int main() {
CBomberman bomberman;
bomberman.PutBomb();
cout << "Bomberman has just put a bomb. Wait for the boom." << endl;
return 0;
}
Your problem is that you're joining the thread immediately after you create it, meaning that you're only using multithreading in a very technical sense: you've definitely created another thread, and it's (probably) going to operate on another CPU core, but the host thread is simply sitting idle while the other thread works.
You need to locally store the thread object so that you can join it at a later point.
class CBomb
{
public:
CBomb ( void )
: m_Owner ( nullptr ),
bomb_thread(&CBomb::Timer, this)
{
}
std::thread bomb_thread; //This needs to be a member of this object. Whether you make it public or not is a matter of your design approach.
private:
void Timer ( void )
{
this_thread::sleep_for( chrono::seconds( 3 ) );
cout << "The bomb has just detonated." << endl;
}
CBomberman * m_Owner;
};
class CBomberman
{
public:
CBomberman ( void )
: m_Bomb ( nullptr )
{
}
bool PutBomb ( void )
{
if( m_Bomb == nullptr )
{
m_Bomb = new CBomb();//Don't delete the object immediately after creating it. What were you expecting to have happen if you did?
return true;
}
else
{
cout << "The bomb has already been put." << endl;
return false;
}
}
CBomb * m_Bomb;
};
int main()
{
CBomberman bomberman;
bomberman.PutBomb();
cout << "Bomberman has just put a bomb. Wait for the boom." << endl;
bomberman.m_bomb->bomb_thread.join(); //If we hit the end before the thread concludes, there could be some errors.
return 0;
}
Because you call join on other_thread immediately after creating other_thread. The join call blocks the main thread and waits for other_thread to exit. See docs on std::thread::join at http://en.cppreference.com/w/cpp/thread/thread/join.
I have written a basic server in C++ that runs in an infinite while loop. It receives signals from a client to do things. The main process that I want is to initiate or stop some tracking software that I have written.
I would like the server to still be able to receive signals while the tracking software is being run (e.g. if a stop signal was given). I figured that the best way to do this would be to create a separate thread for the tracking software, so that is what I did:
void Server::tracking(Command c)
{
//I have since changed this method. The new implementation is below
//switch(c) {
// case START:
// player = VideoPlayer();
// player.setTrackStatus(true);
// t = std::thread(&Server::track, this);
// t.detach();
// break;
// case STOP:
// player.setTrackStatus(false);
// break;
// default:
// break;
//}
}
Server::track just calls player.run()
VideoPlayer is the class that contains the main tracking loop. The track status is what determines whether or not the tracking loop continues to execute.
This works fine the first time I run it, it is able to start the tracking and stop it. The problem arises when I try to send another "START" signal without restarting the server.
I have narrowed down the problem to the cv::namedWindow function.
Here is the start of the VideoPlayer class:
void VideoPlayer::run(void)
{
//I have since changed this method. The new implementation is below
//initVC();
//openStream();
}
initVC() is where I create the namedWindow and openStream contains the main tracking loop. Here is initVC (which is where I believe the problem lies):
void VideoPlayer::initVC()
{
if(!capture.open("cut.mp4")) {
throw "Cannot open video stream";
}
std::cout << "flag 1" << std::endl;
cv::namedWindow("Tracker", CV_WINDOW_AUTOSIZE);
std::cout << "flag 2" << std::endl;
}
I have found that on the second run (i.e. tracking has been started and stopped and the server has not been closed and reopened), that flag 2 never gets run. I also found that, if I omit namedWindow then the program stops before imshow(). It might also be worth noting that the program doesn't crash, it just seems to pause.
I have a feeling that I am doing something wrong with the threading, because I have never used threads in C++ before.
Thanks!
EDIT: I have been attempting to add some of the changes suggested by #Dom, however I am still having a similar issue to before. I will post some additional code below with comments to try to explain.
Server::tracking:
This is meant to initiate tracking based on the command received from the client.
void Server::tracking(Command c)
{
switch(c) {
case START:
if(!isRunning) {
player = make_unique<VideoPlayer>();
isRunning = true;
player->setTrackStatus(isRunning);
}
else {
std::lock_guard<std::mutex> lock(mtx);
}
break;
case STOP:
if(isRunning) {
player->terminate();
player->exit(); //Destroys OpenCV stuff
player->joinThread();
player = nullptr;
isRunning = false;
}
else {
std::lock_guard<std::mutex> lock(mtx);
}
break;
default:
break;
}
}
VideoPlayer Constructor:
VideoPlayer::VideoPlayer () : trackStatus(true)
{
tracker = Tracker(); //A separate class, related to the data from the tracked
//object. Not relevant to the current question
track_t = std::thread(&VideoPlayer::run, this);
return;
}
VideoPlayer::run:
void VideoPlayer::run(void)
{
std::lock_guard<std::mutex> lock(mtx);
initVC(); //Initialises the OpenCV VideoCapture
openStream(); //Contains the main tracking code
return;
}
VideoPlayer::openStream:
void VideoPlayer::openStream()
{
while(trackStatus) {
... //tracking stuff
}
return;
}
VideoPlayer::terminate:
void VideoPlayer::terminate()
{
track = false;
std::lock_guard<std::mutex> lock(mtx);
}
VideoPlayer::joinThread:
void VideoPlayer::joinThread()
{
if(track_t.joinable()) {
std::cout << "flag 1" << std::endl;
track_t.join();
std::cout << "flag 2" << std::endl; //It fails here on my second "run"
return;
}
}
Basically, my program stops just before the track_t.join(), the second time I run the tracking (without restarting the server). flag 1 and flag 2 print the first time that I run the tracking. All of the OpenCV components appear to have been disposed of correctly. If I then try to open the tracking again, firstly, the tracking doesn't seem to start (but the program doesn't crash), and then if I try to stop the tracking, it prints flag 1 but then stops indefinitely without printing flag 2
Sorry for the lengthy post. I hope this gives a bit more context to what I'm trying to achieve
So your tracking app. could be implemented as follows:
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <memory>
#include <atomic>
enum Command : char
{
START = '1',
STOP = '0'
};
static std::mutex mtx; // mutex for I/O stream
class VideoPlayer
{
public:
VideoPlayer() : trackStatus()
{
initVC();
openStream();
};
~VideoPlayer()
{
closeStream();
uninitVC();
}
void setTrackStatus(bool status)
{
if (status && trackStatus == false)
{
trackStatus = status;
t = std::thread(&VideoPlayer::run, this);
}
else
{
trackStatus = false;
if (t.joinable())
{
t.join();
}
}
}
private:
void run()
{
tId = std::this_thread::get_id();
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "run thread: " << tId << std::endl;
}
while (trackStatus)
{
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "...running thread: " << tId << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1)); // encode chunk of stream and play, whatever....
}
}
void initVC()
{
/*
if (!capture.open("cut.mp4"))
{
throw "Cannot open video stream"; --> http://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads
}
std::cout << "flag 1" << std::endl;
//cv::namedWindow("Tracker", CV_WINDOW_AUTOSIZE);
//std::cout << "flag 2" << std::endl;
*/
}
void uninitVC()
{
}
void openStream()
{
}
void closeStream()
{
}
private:
std::atomic<bool> trackStatus; // atomic, because of access from another (main) thread
std::thread t; // thread for "tracking"
std::thread::id tId; // ID of the "tracking" thread
};
class Server
{
public:
Server() : isRunning(), player(std::make_unique<VideoPlayer>())
{
}
~Server() = default;
void tracking(Command c)
{
switch (c)
{
case START:
if (!isRunning)
{
isRunning = true;
player->setTrackStatus(isRunning);
}
else
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Player is already running...\n";
}
break;
case STOP:
if (isRunning)
{
player->setTrackStatus(!isRunning);
isRunning = false;
}
else
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Player is not running...\n";
}
break;
default:
break;
}
}
private:
std::unique_ptr<VideoPlayer> player;
bool isRunning;
};
int main()
{
std::cout << "main thread: " << std::this_thread::get_id() << std::endl;
Server srv;
char cmd = -1;
while (std::cin >> cmd)
{
switch (cmd)
{
case Command::START:
{
srv.tracking(Command::START);
}
break;
case Command::STOP:
{
srv.tracking(Command::STOP);
}
break;
default:
std::cout << "Unknown command...\n";
break;
}
}
}
You can move creation of the thread to constructor of VideoPlayer and join in destructor (I would prefer it...):
VideoPlayer() : trackStatus(true)
{
initVC();
openStream();
t = std::thread(&VideoPlayer::run, this);
};
~VideoPlayer()
{
closeStream();
uninitVC();
if (t.joinable())
{
t.join();
}
}
but some modifications are needed to terminate and clean the thread, you can use something like
public:
void VideoPlayer::terminate()
{
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "terminate thread: " << tId << std::endl;
}
trackStatus = false;
}
however, than is needed to create instance of player during START
player = std::make_unique<VideoPlayer>();
and then Terminate() and delete the player during STOP
player->terminate();
player = nullptr;
Hope, this inspired you enough ;-)