I write a simple program for testing Thread in c++11 but std::cout
doesnt work as I expect.
class Printer
{
public:
void exec()
{
mutex m;
m.lock();
cout<<"Hello "<<this_thread::get_id()<<endl;
chrono::milliseconds duration( 100 );
this_thread::sleep_for( duration );
m.unlock();
}
};
int main()
{
Printer printer;
thread firstThread([&printer](){
while(1)
printer.exec();
});
thread secondThread([&printer](){
while(1)
printer.exec();
});
firstThread.join();
secondThread.join();
}
some of the results :
Hello 11376
Hello 16076
Hello 16076
Hello Hello 11376
16076
Hello 11376
,....
I used mutex for locking threads so I cant understand why two threads are executing std::cout
at the same time.
It seams very weired to me.Can any one explain what is happening!?!
The threads are using different mutex
instances as the mutex
is a local variable in the exec()
function so locking the mutex
is pointless as each thread will be locking its own mutex
resulting in no synchronization between the threads. The same mutex
instance must be used by the threads to achieve synchronization.
To correct in the posted code, make the mutex
a member variable. However, if another Printer
object was created then there would be no synchronization between threads that used different Printer
instances. In this case, the mutex
would need to be a static
member variable to ensure synchronization:
class Printer
{
public:
//...
private:
static std::mutex mtx_;
};
std::mutex Printer::mtx_;
To ensure a mutex
is always released, regardless if a function exits normally or via an exception, use std:lock_guard
:
std::lock_guard<std::mutex> lock(m); // 'm' locked, and will be
// unlocked when 'lock' is destroyed.
std::cout<< "Hello " << std::this_thread::get_id() << std::endl;
std::chrono::milliseconds duration( 100 );
std::this_thread::sleep_for( duration );
The accepted answer is correct. However it is nice to separate concerns:
std::cout
in a thread safe manner.Here is a utility I use that just concentrates on collecting arguments to std::cout
and streaming them out under a static std::mutex
:
#include <iostream>
#include <mutex>
std::ostream&
print_one(std::ostream& os)
{
return os;
}
template <class A0, class ...Args>
std::ostream&
print_one(std::ostream& os, const A0& a0, const Args& ...args)
{
os << a0;
return print_one(os, args...);
}
template <class ...Args>
std::ostream&
print(std::ostream& os, const Args& ...args)
{
return print_one(os, args...);
}
std::mutex&
get_cout_mutex()
{
static std::mutex m;
return m;
}
template <class ...Args>
std::ostream&
print(const Args& ...args)
{
std::lock_guard<std::mutex> _(get_cout_mutex());
return print(std::cout, args...);
}
This code can be reused for streams other than std::cout
, but the above is specialized to just target std::cout
. With this your Printer::exec()
can now be significantly simplified:
void exec()
{
print("Hello ", std::this_thread::get_id(), '\n');
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
Now, not only will your Printer
use cout
in a threadsafe manner, and has been simplified (e.g. doesn't need to maintain its own mutex
for cout
), but all of your other types and functions can also use cout
and all interoperate together safely. The print
function itself now maintains the mutex
, and that fact is encapsulated away from all of print
's clients.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With