No need for global variables. Remember that thread routines can take parameters, so this can be any variable, including dynamically allocated ones.
Usually you need to โwrapโ the stream in the class, something like strings:
struct Thread { Thread() : m_thread(&Thread::run, this) {} void run() {
But if we put aside this small detail of global variables, your No. 1 will be right ... Communication through variables (whether message queues, booleans, whatever), protected by a mutex and optionally condition_variable (to act as an awakening trigger) is almost always the way to go.
I for almost always ends up using thread-safe message queues (i.e. std::queue + mutex + condition_variable ) for communication between threads (producer / consumer pattern), this is a very efficient way to isolate threads and allow them to communicate.
In fact, there are very few cases where in one process something more than direct access to memory makes sense.
All that I can think about now, if you already have some working interprocessor code (for example, sockets or shared memory), you can reuse this code to provide a uniform interface in the process or interprocess communication. But do not be fooled, it will be less effective than direct access to memory. However, the benefits of a consistent interface can easily overcome the loss of efficiency. IMHO, you really need to deal with such things in each case.
source share