using std::cout in multiple threads using std::cout in multiple threads multithreading multithreading

using std::cout in multiple threads


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:

  1. You need a way to print to std::cout in a thread safe manner.
  2. You need to create objects/functors/functions to run in threads and launch them.

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.


I'm sharing the trick from Nicolás given in this question that I find to be more elegant than Howard Hinnant implementation. The idea is to create a temporary ostringstream object and put the protection code on the destructor.

/** Thread safe cout class  * Exemple of use:  *    PrintThread{} << "Hello world!" << std::endl;  */class PrintThread: public std::ostringstream{public:    PrintThread() = default;    ~PrintThread()    {        std::lock_guard<std::mutex> guard(_mutexPrint);        std::cout << this->str();    }private:    static std::mutex _mutexPrint;};std::mutex PrintThread::_mutexPrint{};

You can then use it as a regular std::cout, from any thread:

PrintThread{} << "val = " << 33 << std::endl;

The object collect data as a regular std::ostringstream. As soon the coma is reached, the object is destroyed and flush all collected information.