Code:
#include <iostream>
#include <future>
#include <queue>
#include <boost/thread/thread.hpp>
boost::mutex mtx;
std::queue<std::string>ev;
void t_1(){
while(true){
mtx.lock();
if(ev.size() > 0){
std::cout << ev.front();
ev.pop();
}
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
}
}
void t_2(){
int x = 0;
while(true){
x++;
mtx.lock();
ev.push("new event");
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}
}
void t_3(){
while(true){
std::cout << 3;
}
}
int main(int argc, const char * argv[]) {
// insert code here...
boost::thread t1(t_1);
boost::thread t2(t_2);
//boost::thread t3(t_3);
t1.join();
t2.join();
while(true){
std::cout << "anyone there";
}
//t3.join();
return 0;
}
I was messing around with the boost library, and wanted to make an event checker using threads and mutexes. For some reason there is no output, even on the main thread when it should print "anyone there." I am using Mac OSX and Xcode. THe program compiles and runs just fine.
As already mentioned by #krzaq your main loop does not print anything because join waits for the termination of the thread, which will never happen due to the endless loops in t_1 and t_2.
As for your t_1 output: You have no newline in your output. Typically the output buffer is flushed only on a newline, which means that you will not see the output flushed to your terminal until you either print a newline or the buffer is filled up.
Try this:
std::cout << ev.front() << "\n";
Your threads never finish, and you join() them (that is, wait for them to finish) before the printing loop in the main thread.
t1.join(); // the main thread never gets past this point
Related
I'm new to C++ and am trying to have two threads run:
i) Thread that keeps looping until an atomic bool is flipped.
ii) A thread that polls for input from keyboard and flips the atomic bool.
I seem to be unable to get std::cin.get() to react to an input unless it is assigned its' own thread (like below). Why? Would it not then be set from the parent main thread?
#include <iostream>
#include <iomanip> // To set decimal places.
#include <thread> //std::thread
#include <atomic> //for atomic boolean shared between threads.
#include <math.h>
#define USE_MATH_DEFINES //For PI
std::atomic<bool> keepRunning(false); //set to false to avoid compiler optimising away.
void loop(){
int t = 1;
while(!keepRunning.load(std::memory_order_acquire)) //lower cost than directly polling atomic bool?
{
//Write sine wave output to console.
std::cout << std::setprecision(3) << sin(M_PI * 2 * t/100) << std::endl;
(t<101)? t++ : t = 1;
}
}
//This works, as opposed to stopping in main.
void countSafe(){
int j = 1;
while (j<1E7)
{
j++;
}
keepRunning.store(true, std::memory_order_release); //ends the loop thread.
}
int main(){
std::thread first (loop); //start the loop thread
std::thread second (countSafe); //start the countSafe thread. Without this it doesn't work.
//Why does polling for std::cin.get() here not work?
//std::cin.get(); //wait for key press. puts in buffer..?
//keepRunning.store(true, std::memory_order_release); //Set stop to true.
second.join(); //pause to join.
first.join(); //pause to join
return 0;
}
I'm not quite sure what your problem is, but use of cin.get() might be part of it. Let's simplify with this code:
#include <iostream>
using namespace std;
int main(int, char **) {
cout << "Type something: ";
cin.get();
cout << "Done.\n";
}
Try that code and run it. Then type a single character. Chances are that the code won't recognize it. And you can type all you want until you hit return.
This is complicated, but your program doesn't actually receive the characters until you hit return unless you play other games. Like I said, it's complicated.
It's possible behavior is different on Windows, but this is the behavior on Mac and Linux.
So is it "not working" because you tried typing a space but you really need to use Return?
I am trying to run run() function every 5 seconds without stopping while() loop (parallelly). How can I do that ? Thanks in advance
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void run()
{
this_thread::sleep_for(chrono::milliseconds(5000));
cout << "good morning" << endl;
}
int main()
{
thread t1(run);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}
In your main function, it is important to understand what each thread is doing.
The main thread creates a std::thread called t1
The main thread continues and detaches the thread
The main thread executes your while loop in which it:
prints hello
sleeps for 0.5 seconds
The main thread returns 0, your program is finished.
Any time from point 1, thread t1 sleeps for 5 seconds and then prints good morning. This happens only once! Also, as pointed out by #Fareanor, std::cout is not thread-safe, so accessing it with the main thread and thread t1 may result in a data race.
When the main thread reaches point 4 (it actually never does because your while loop is infinite), your thread t1 might have finished it's task or not. Imagine the potential problems that could occur. In most of the cases, you'll want to use std::thread::join().
To solve your problem, there are several alternatives. In the following, we will assume that the execution of the function run without the std::this_thread::sleep_for is insignificant compared to 5 seconds, as per the comment of #Landstalker. The execution time of run will then be 5 seconds plus some insignificant time.
As suggested in the comments, instead of executing the function run every 5 seconds, you could simply execute the body of run every 5 seconds by placing a while loop inside of that function:
void run()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
}
int main()
{
std::thread t(run);
t.join();
return 0;
}
If, for some reason, you really need to execute the run function every 5 seconds as stated in your question, you could launch a wrapper function or lambda which contains the while loop:
void run()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
int main()
{
auto exec_run = [](){ while (true) run(); };
std::thread t(exec_run);
t.join();
return 0;
}
As a side note, it's better to avoid using namespace std.
Just call your run function in seperate thread function like below. Is this ok for you?
void ThreadFunction()
{
while(true) {
run();
this_thread::sleep_for(chrono::milliseconds(5000));
}
}
void run()
{
cout << "good morning" << endl;
}
int main()
{
thread t1(ThreadFunction);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}
I am currently trying to learn how to use a condition_variable for thread synchronization. For testing, I have made the demo application shown below. When I start it, it runs into a dead lock. I know the location where this happens, but I'm unable to understand why the deadlock occurs.
I know that a condition_variable's wait function will automatically unlock the mutex when the condition is not true, so the main thread should not be blocked in the second pass. But it is just this what happens.
Could anybody explain why?
#include <thread>
#include <condition_variable>
#include <iostream>
bool flag = false;
std::mutex g_mutex;
std::condition_variable cv;
void threadProc()
{
std::unique_lock<std::mutex> lck(g_mutex);
while (true)
{
static int count = 0;
std::cout << "wait for flag" << ++count << std::endl;
cv.wait(lck, []() {return flag; }); // !!!It will blocked at the second round
std::cout << "flag is true " << count << std::endl;
flag = false;
lck.unlock();
}
}
int main(int argc, char *argv[])
{
std::thread t(threadProc);
while (true)
{
static int count = 0;
{
std::lock_guard<std::mutex> guard(g_mutex); // !!!It will blocked at the second round
flag = true;
std::cout << "set flag " << ++count << std::endl;
}
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
t.join();
return 0;
}
I know that a condition_variable's wait function will automatically unlock the mutex when the condition is not true.
Um..., yes..., Just to be absolutely clear, cv.wait(lck, f) does this:
while(! f()) {
cv.wait(lck);
}
And each call to cv.wait(lck) will;
unlock lck,
wait until some other thread calls cv.notify_one() or cv.notify_all(),
re-lock lck, and then
return.
You can fix the problem by moving the unique_lock(...) statement inside the while loop. As it is now, you're attempting to unlock lck on round 2 but it was not in a locked state, since, after round 1 you never locked it again.
I'm trying to run a thread with a function from a class member and use conditional variable to wait until the main thread signals and add the times the thread got signaled. Here is the code:
// Example program
#include <iostream>
#include <string>
#include <atomic>
#include <thread>
#include <unistd.h>
#include <mutex>
#include <condition_variable>
std::mutex m_mutex;
std::condition_variable m_condVar;
char stop =0;
class dummclass
{
std::thread dummclass_thread;
int alarms;
public:
dummclass() :
alarms(0),
dummclass_thread(std::thread(&dummclass::dummclassThreadProc, this))
{
}
~dummclass()
{
std::cout<<"Alarms: "<<alarms<<"\n";
//signal thread before joining
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
stop=1;
}
m_condVar.notify_one();
dummclass_thread.join();
}
private:
void dummclassThreadProc()
{
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout<<"thread waiting\n";
m_condVar.wait(mlock);
std::cout<<"thread done waiting\n";
}
sleep(1);
std::unique_lock<std::mutex> mlock(m_mutex);
while (!stop)//!stop_dummclass.load())
{
std::cout<<"got mutex\n";
m_condVar.wait(mlock);
std::cout<<"wait done\n";
{
std::cout<<"got one\n";
alarms++;
}
}
std::cout<<"end loop\n";
}
};
int main()
{
dummclass *x = new dummclass;
sleep(3);
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
}
m_condVar.notify_one();
std::cout<<"done waiting\n";
sleep(3);
for(int i=0;i<13;i++)
{
{
std::cout<<"signal "<<i<<"\n";
std::lock_guard<std::mutex> lock_guard(m_mutex);
}
m_condVar.notify_one();
}
delete x;
}
The weird part is that the initial waiting and signaling that are outside of the loops actually work ok. I don't understand what mistake I do so that the while loop inside the class thread doesn't catch any signal from the main thread but it catches a signal from the destructor of the dummyclass when I delete it. This is the output:
thread waiting
done waiting
thread done waiting
got mutex
signal 0 signal 1 signal 2 signal 3 signal 4 signal 5 signal 6 signal 7 signal
8 signal 9 signal 10 signal 11 signal 12
Alarms: 0
wait done
got one end loop
EDIT: It seems that adding a 1 second sleep in the main() for loop solves the problem. Is it possible that the for loop gets the mutex before wait() manages to wake and lock the mutex ?
for(int i=0;i<13;i++)
{
{std::cout<<"signal "<<i<<"\n";
std::lock_guard<std::mutex> lock_guard(m_mutex);}
m_condVar.notify_one();
sleep(1);
}
Can someone please show me what is wrong ?
Thanks.
The object doing the waiting gets deleted before it processes the signal. Since the delete happens on a known to be running thread it has a fair chance to get executed first. In particular it is also likely to reacquire the lock again: Since the notify_one() is done while the mutex is locked the wait()ing thread cannot acquire it and will go back to sleep, waiting for the mutex to be released. That gives the signalling thread an opportunity to reacquire the lock. The only forced synchronizqtion causing the signalling thread to wait is the join() and it does give the waiting thread a chance to execute.
Note that signals of condition variables are not something delivered to the waiting thread. They are essentially wake-up calls. The waiting thread will wake up eventually once a signal is delivered. However, many signals can be delivered before it actually does so.
I don't understand what mistake I do so that the while loop inside the
class thread doesn't catch any signal from the main thread
Even though multiple notifications are sent the thread may only receive a single notification.
The notify_one() call does
not mean that the current thread will stop and wait for another thread.
It just means that the other thread must wake up at some point because something may have happened that it would be interested in.
Also note that std::condition_variable::wait could experience a spurious wakeup, so it might not even have anything to do or have received a 'real' signal.
The solution is to provide a predicate as a parameter to the wait() call. The predicate can then check if there is a signal (via a variable provided for this purpose and only changed under lock) and may also check if the program has been stopped.
In the updated program below I've added a predicate to the wait and made some minor changes. The program only notifies under lock, but you might choose not to.
// Example program - modified
#include <iostream>
#include <string>
#include <atomic>
#include <thread>
//#include <unistd.h>
#include <mutex>
#include <condition_variable>
#include <chrono>
std::mutex m_mutex;
std::condition_variable m_condVar;
bool signal_waiting{false};
bool stop{false};
class dummclass
{
int alarms{};
std::thread dummclass_thread{[this](){dummclassThreadProc(); }};
public:
~dummclass()
{
std::cout << "Alarms: " << alarms << "\n";
//signal thread before joining
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
stop = 1;
m_condVar.notify_one();
}
dummclass_thread.join();
}
private:
void dummclassThreadProc()
{
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout << "thread waiting\n";
m_condVar.wait(mlock);
std::cout << "thread done waiting\n";
}
std::this_thread::sleep_for(std::chrono::seconds{1});
while(!stop)//!stop_dummclass.load())
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout << "got mutex\n";
//m_condVar.wait(mlock);
m_condVar.wait(mlock, [](){return signal_waiting || stop; });
if(stop)
break;
std::cout << "wait done\n";
std::cout << "got one\n";
alarms++;
signal_waiting = false;
m_condVar.notify_one();
}
std::cout << "end loop\n";
}
};
int main()
{
dummclass *x = new dummclass;
//sleep(3);
std::this_thread::sleep_for(std::chrono::seconds{1});
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
m_condVar.notify_one();
}
std::cout << "done waiting\n";
//sleep(3);
std::this_thread::sleep_for(std::chrono::seconds{1});
for(int i = 0; i<13; i++)
{
{
std::cout << "signal " << i << "\n";
std::unique_lock<std::mutex> lock(m_mutex);
m_condVar.wait(lock, [](){return !signal_waiting ; });
signal_waiting = true;
m_condVar.notify_one();
}
}
delete x;
}
I wrote the following code and am unable to understand why doesn't it prints out all the no's(i.e. 0 to -99) in threadFunc() as it does with main() thread.
#include<iostream>
#include<thread>
#include<string>
#include<mutex>
#include<chrono>
using namespace std;
mutex mu;
void threadFunc(){
for(int i=0;i>-100;i--){
std::this_thread::sleep_for(std::chrono::milliseconds(30)); /*delay for 30ms*/
mu.lock();
cout<<"Thread: "<<i<<endl;
mu.unlock();
}
}
main(){
thread t1(threadFunc);
for(int i=0;i<100;i++){
mu.lock();
cout<<"Main: "<<i<<endl;
mu.unlock();
}
cout<<"End of Main"<<endl;
t1.detach();
}
The output of the program is:
Main: 0
Main: 1
.
.
.
Main: 99
End of Main.
Thread: -1
Process terminates when main() exits, and all threads are killed. You observe this behavior in your program.
Detach basically says that from now on, you can't join this thread. But if you can't join it, you can't make your main() to wait until it completes (unless you use other synchronization primitives) - and thus it is happily exiting.
This is why I strongly discourage everybody from using detached threads, they are very hard to do properly.
The detach function prevents an exception from being thrown when the thread object goes out of scope. Usually, you would want to call join but if you don't want to block the execution you need to call detach. However, you probably need to use another synchronization mechanism to make sure everything is fine if the thread is still running when main is ready to exit. See the following contrived example.
Example Code
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
std::mutex mu;
std::condition_variable cv;
bool finished = false;
void threadFunc()
{
for (int i = 0; i < 5; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
std::unique_lock<std::mutex> lock(mu);
std:: cout << "Thread: " << (0 - i) << "\n";
}
std::unique_lock<std::mutex> lock(mu);
finished = true;
cv.notify_one();
}
int main()
{
{
std::thread t1(threadFunc);
t1.detach(); // Call `detach` to prevent blocking this thread
} // Need to call `join` or `detach` before `thread` goes out of scope
for (int i = 0; i < 5; ++i)
{
std::unique_lock<std::mutex> lock(mu);
std::cout << "Main: " << i << "\n";
}
std::cout << "End of Main\n";
std::unique_lock<std::mutex> lock(mu);
cv.wait(lock, [&finished]() { return finished; });
return 0;
}
Example Output
Main: 0
Main: 1
Main: 2
Main: 3
Main: 4
End of Main
Thread: 0
Thread: -1
Thread: -2
Thread: -3
Thread: -4
Live Example
Again, the above is a contrived example and in your case you could more easily use join instead of detach before allowing main to return.