I try to learn how to use C++11 thread library and then, I am confused about the output of my following code.
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void thread_function()
{
std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;
}
int main()
{
std::thread threadObj1(thread_function);
std::thread threadObj2(thread_function);
if (threadObj1.get_id() != threadObj2.get_id())
std::cout << "Both threads have different id" << std::endl;
threadObj1.join();
threadObj2.join();
std::cout<<"From Main Thread :: ID of Thread 1 = "<<threadObj1.get_id()<<std::endl;
std::cout<<"From Main Thread :: ID of Thread 2 = "<<threadObj2.get_id()<<std::endl;
return 0;
}
I attach every std::cout with std::endl in order to flush the buffer and output the '/n' character. However, finally I got the output as the following.
Both threads have different idInside Thread :: ID = Inside Thread :: ID =
0x700003715000
0x700003692000
From Main Thread :: ID of Thread 1 = 0x0
From Main Thread :: ID of Thread 2 = 0x0
Program ended with exit code: 0
It seems that the '/n' before the Inside Thread disappeared. Could you please help me figure it out? Thank you so much!
You have 3 threads which are accessing cout without any synchronization. You have defined mtx but it is not used, why?
Add lock_guard to protect cout statement:
void thread_function()
{
std::lock_guard<std::mutex> lk{mtx};
std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;
}
if (threadObj1.get_id() != threadObj2.get_id())
{
std::lock_guard<std::mutex> lk{mtx};
std::cout << "Both threads have different id" << std::endl;
}
I think I should also receive three '\n' right?
The three '\n' characters in question are there in your output. They're at the ends of the first three lines of output.
I think maybe you misunderstand what this line from your example means:
std::cout << "Inside Thread :: ID = " << std::this_thread::get_id() << std::endl;
There are four separate function calls explicit in that one line of code. That one line does exactly the same thing as these four lines:
std::cout << "Inside Thread :: ID = ";
auto id = std::this_thread::get_id();
std::cout << id;
std::cout << std::endl;
Even assuming that the std::cout object is fully synchronized, You have done nothing to prevent the various threads from interleaving the separate function calls. E.g.,
main thread calls std::cout << "Both threads have different id";
threadObj1 calls std::cout << "Inside Thread :: ID = ";
threadObj2 calls std::cout << "Inside Thread :: ID = ";
main thread calls std::cout << std::endl;
threadObj1 calls std::cout << std::this_thread::get_id();
threadObj1 calls stc::cout << std::endl;
etc.
Related
When I run the following code,
#include <thread>
#include <iostream>
#include <future>
int main() {
auto fut = std::async(
std::launch::async,
[]{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "sub : " << std::this_thread::get_id() << std::endl;
}
);
std::cout << "do some on main thread" << std::endl;
fut.get();
std::cout << "main: " << std::this_thread::get_id() << std::endl;
}
I got the following output.
do some on main thread
sub : 139899103246080
main: 139899103250240
Running demo: https://godbolt.org/z/c9WedY4oq
It is the same behavior as I expected.
"do some on main thread" outputs first, because the sub thread created by std::async() waits 1 second the beggining of the thread.
So far, so good.
However, when I removed the variable fut, then I got weird behavior for me.
NOTE: This code is for only experimental purpose
#include <thread>
#include <iostream>
#include <future>
int main() {
std::async(
std::launch::async,
[]{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "sub : " << std::this_thread::get_id() << std::endl;
}
);
std::cout << "do some on main thread" << std::endl;
std::cout << "main: " << std::this_thread::get_id() << std::endl;
}
Here is the output:
sub : 139716056966912
do some on main thread
main: 139716056971072
Running demo: https://godbolt.org/z/obzzceGGr
It seems that the main thread waits until finishing the sub thread before outputing "do some on main thread".
I want to know why this behavior happens.
I got the warning message ":6:5: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]".
Since C++20, the nodiscard attribute has been added.
See https://en.cppreference.com/w/cpp/thread/async
I guess that I got an undefined behavior due to ignoring the return value of std::async(), but I couldn't find such document, so far.
In the second case, a std::future object will still be created and returned.
That object is ephemeral and will be destructed immediately, and that leads to your problem because the std::future destructor will wait for the future to be ready before destruction continues.
I have a main program, this main program executes a thread that perform an action until the user triggers a stop. The problem that I have is if I add th.join() the main program won't continue until the thread finishes. And If there is no .join() the program crashs.
#include <iostream>
#include <thread>
#include <optional>
static bool s_finished = false;
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
void startRecording(std::optional<int> t)
{
std::thread th1 (SendData, 1);
//th1.join();
std::cout << "[startRecording] Other Task" << std::endl;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
startRecording();
std::this_thread::sleep_for(5s);
stopRecording();
return 0;
}
How can I do this?
Joining a thread will cause the program to stop until that thread is finished, and that's why the program blocks. We have to call join() eventually so that all child threads finish before the program exits, but we shouldn't call join until we need the child thread to be finished.
The simplest way to get the program to work is to return the thread from startRecording, so that we have control of it inside main. Then, we join the thread at the end of main, after we call stopRecording.
#include <iostream>
#include <thread>
#include <optional>
#include <atomic>
// (1) This needs to be atomic to avoid data races
std::atomic<bool> s_finished { false };
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
std::thread startRecording(std::optional<int> t)
{
std::thread th1 (SendData, 1);
std::cout << "[startRecording] Other Task" << std::endl;
// (2) We return the thread so we can join it in main:
return th1;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
// (3) We save the thread to a variable named 'worker'
// so we can join it later. I also added an input to startRecording b/c it needed one
std::thread worker = startRecording(std::optional<int>{1});
std::this_thread::sleep_for(5s);
stopRecording();
// (4) Join here, at the end
worker.join();
return 0;
}
Now, the program prints the expected output, then exits without problems:
Start Program!
[startRecording] Other Task
Working thread: 1
Started thread id: 139985258444544
Working
Working
Working
Working
Working
[stopRecording] Other Task
I marked my changes with (1), (2), (3), and (4) in the comments of the code. They're pretty small, and if you have questions about any of them I can provide additional explanation!
Addendum - using global variables when the signature of startRecording can't be changed
In general, it's best to avoid global variables, but I know it's not always possible to do so. if startRecording's signature can't be changed, we can't return a thread, so the thread has to be accessed globally. Here's how to do that:
#include <iostream>
#include <thread>
#include <optional>
#include <atomic>
// (1) This needs to be atomic to avoid data races
std::atomic<bool> s_finished { false };
// (2) we initialize this in startRecording
std::thread worker;
using namespace std::literals::chrono_literals;
void SendData(int id)
{
std::cout << "Working thread: " << id << std::endl;
std::cout << "Started thread id: " << std::this_thread::get_id() << std::endl;
while (!s_finished)
{
std::cout << "Working\n";
std::this_thread::sleep_for(1s);
}
}
void startRecording(std::optional<int> t)
{
// (3) worker gets initialized, and thread starts
worker = std::thread(SendData, 1);
std::cout << "[startRecording] Other Task" << std::endl;
}
void stopRecording()
{
s_finished = true;
std::cout << "[stopRecording] Other Task" << std::endl;
}
int main()
{
std::cout << "Start Program!" << std::endl;
startRecording(std::optional<int>{1});
std::this_thread::sleep_for(5s);
stopRecording();
// (4) Join here, at the end
worker.join();
return 0;
}
In this program, I'm trying to print my username and then create two threads. I want each thread to print its thread id and go into a loop and display something periodically.
Here is the code I have
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <string>
void task(std::string threadNum)
{
std::thread::id this_id = std::this_thread::get_id();
std::cout << threadNum << " : " << this_id << std::endl;
for(int i=0; i<1000; i++){
if(i == 300 or i == 600 or i == 900){
std::cout << threadNum << " has reached step: " << i << std::endl;
}
}
}
int main()
{
std::cout << "Your Username Is: " << getenv("USER") << std::endl;
std::thread t1(task, "Thread 1");
std::thread t2(task, "Thread 2");
t1.join();
t2.join();
}
and I get different outputs every single time I run the program, for example
Your Username Is: gansaikhanshur
Thread 2 : Thread 1 : 0x70000741e000
Thread 2 has reached step: 0x70000739b000300
Thread 1 has reached step: 300
Thread 2 has reached step: 600
Thread 2 has reached step: 900
Thread 1 has reached step: 600
Thread 1 has reached step: 900
Thread1 and Thread 2 does not show it's thread ID as it should. Why do I get different results all the time? and Is it possible for me to make thread 1 and thread 2 to display their correct thread ids?
This is the way threads work -- they run independently and any side-effects they have may show up interleaved in any order. If you want to ensure that doesn't happen, you need to synchronize. For example, if you want to ensure that lines written to cout don't get mixed up, you can lock around each line output:
std::mutex cout_lock;
void task(std::string threadNum)
{
std::thread::id this_id = std::this_thread::get_id();
{
std::lock_guard<std::mutex> lock(cout_lock);
std::cout << threadNum << " : " << this_id << std::endl;
}
for(int i=0; i<1000; i++){
if(i == 300 or i == 600 or i == 900) {
std::lock_guard<std::mutex> lock(cout_lock);
std::cout << threadNum << " has reached step: " << i << std::endl;
}
}
}
lock_guard gives you a nice easy exception-safe way to manage lock/unlock operations.
I'm using boost 1.54.0 and Visual Studio 2010. For the code:
#include <iostream>
#include "boost/thread/thread.hpp"
#include "boost/thread/mutex.hpp"
boost::mutex mx1;
void func1()
{
{
boost::mutex::scoped_lock(mx1);
std::cout << "Thread " << boost::this_thread::get_id() << " starting work." << std::endl;
}
int x = 0;
for (int i=0; i<100; i++)
x++;
{
boost::mutex::scoped_lock(mx1);
std::cout << "Thread " << boost::this_thread::get_id() << " finished." << std::endl;
}
}
int main(void)
{
boost::thread thread1(&func1);
boost::thread thread2(&func1);
thread1.join();
thread2.join();
return 0;
}
About half the time I get the following (with varying thread ids and execution order, obviously):
Thread Thread 15b0 starting work.
1a18 starting work.
Thread 15b0 finished.
Thread 1a18 finished.
...instead of this (which is what I'd expect):
Thread 15b0 starting work.
Thread 1a18 starting work.
Thread 15b0 finished.
Thread 1a18 finished.
However, using
mx1.lock();
std::cout << "Thread " << boost::this_thread::get_id() << " starting work." << std::endl;
mx1.unlock();
...seems to work with no problems.
The output always seems to follow the same pattern. Am I using the mutex incorrectly, or is it something to do with std::cout?
Replace
boost::mutex::scoped_lock(mx1);
with
boost::mutex::scoped_lock lock(mx1);
you fell a victim of the most frequently occurring typo with the scoped lock:-)
I have blocking task which will be performed by find_the_question() function. However, I do not want thread executing this function take more than 10 seconds. So in case it takes more than 10 seconds, I want to close that thread with cleaning all the resources.
I tried to write a code for that, but somehow I am not able to get a interrupt in find_the_question() function if thread takes more than 10 seconds. Could you please tell me what am I doing wrong?
void find_the_question(std::string value)
{
//allocate x resources
try{
//do some process on resources
sleep(14);
//clean resources
}
catch(boost::thread_interrupted const& )
{
//clean resources
std::cout << "Worker thread interrupted" << std::endl;
}
}
int main()
{
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000);
std::cout << "In main" << std::endl;
boost::thread t1(find_the_question, "Can you block me");
t1.interrupt();
if (t1.timed_join(timeout))
{
//finished
std::cout << "Worker thread finished" << std::endl;
}
else
{
//Not finished;
std::cout << "Worker thread not finished" << std::endl;
}
std::cout << "In main end" << std::endl;
}
Output:
If t1 takes more than 10 seconds to complete, I am getting following console output.
std::cout << "In main" << std::endl;
std::cout << "Worker thread not finished" << std::endl;
std::cout << "In main end" << std::endl;
whereas, I am expecting following output
std::cout << "In main" << std::endl;
std::cout << "Worker thread interrupted" << std::endl;
std::cout << "Worker thread not finished" << std::endl;
std::cout << "In main end" << std::endl;
Could you please tell me what am I doing wrong.
Thanks in advance
For using boost::thread::interrupt(), you have to use boost::thread::sleep() for it to work.
A running thread can be interrupted by invoking the interrupt() member
function of the corresponding boost::thread object. When the
interrupted thread next executes one of the specified interruption
points (or if it is currently blocked whilst executing one) with
interruption enabled, then a boost::thread_interrupted exception will
be thrown in the interrupted thread. If not caught, this will cause
the execution of the interrupted thread to terminate. As with any
other exception, the stack will be unwound, and destructors for
objects of automatic storage duration will be executed
Predefined interruption points:
The following functions are interruption points, which will throw
boost::thread_interrupted if interruption is enabled for the current
thread, and interruption is requested for the current thread:
boost::thread::join()
boost::thread::timed_join()
boost::condition_variable::wait()
boost::condition_variable::timed_wait()
boost::condition_variable_any::wait()
boost::condition_variable_any::timed_wait()
boost::thread::sleep()
boost::this_thread::sleep()
boost::this_thread::interruption_point()