Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ Best Way to Share state between threads

The scenario is as follows: Thread A keeps executing until it receives a stop signal from thread B that keeps reading input from the console.

What is the best way to implement this? For example, I think I could implement it as a global variable that thread A keeps checking every once in a while, and thread B can change to signal "stop",

But I don't know if this is the correct way.

  • Even if it's correct, should I use "Volatile" or "Atomic<>"? Especially that thread A only reads the value of the variable and thread B only writes to the variable.

  • And what if modifying the variable from thread B right after thread A has read it doesn't matter (doesn't cause problem "thread A quitting time is somewhat relaxed(tolerated after the signal)")?

  • Is there another way for thread B to start thread A and stop it when it wants to?

like image 834
Oz Le Avatar asked Feb 17 '15 17:02

Oz Le


People also ask

Is it possible to share data between threads and processes?

As people have already noted you are creating processes not threads. Sharing data among processes is harder. Every process has its own memory address space which means that they may share same code, but their data is private.

Should I share mutable data between threads?

If you want to have fun with threads, you should share mutable data between them. In order to get no data race and, therefore, undefined behavior, you have to think about the synchronization of your threads.

When an object is shared between threads in C++?

The scenarios when an object is shared between threads in C++ can be divided into two categories - a "read-only" one where the object is never modified, and a "non-read-only" one. Scenarios in the non-read-only category are going to require an access control mechanism.

How to share data from one process to another?

in case you are thinking of threads use pthreads incase you are looking for processes you need to use IPC mechanisms Use any IPC to share data b/w processes. In threads the data can be shared by following methods: return value of thread passed to pthread_exit and catch in pthread_join


2 Answers

The question will probably be closed as "too broad", however I will try to answer it (in the same "broad" fashion).

The only imaginable answer here is: "it depends" (c)

General advise: Try, and keep it simple (KISS principle). Start with a simple solution (like mutexes in your case), and if you ever find it unsatisfactory, replace it with another, more complex but efficient/scalable/customizable/pleasant thing (let's say atomics). If any of this will proof to be insufficient, grow complexity further (relax atomics, add lock-free stuff, build up task-based concurrency, whatever you may need) until you find the right balance.

like image 60
Ivan Aksamentov - Drop Avatar answered Oct 06 '22 11:10

Ivan Aksamentov - Drop


You don't really want to stop a thread, rather you want to signal it to stop when it is in a good spot.

It doesn't have to be a global variable. You can pass the address of a struct to a thread. That struct could contain a flag. If another thread knew the address of the struct, then it could change the flag. You could have a global array of structs, one for each thread you have running. There are lots of ways for more than one thread to work with the same data.

You could use signals. These are handy if the thread you want to close is sleeping.

Some people like to use mutexes and condition variables. Others like to use atomic operations. If you are just testing a global int to see if it is non zero, a mutex is typically not necessary.

In this case a global int would work fine. You could make it volatile if you wanted. This tells the compiler to not optimize a variable in ways that would prevent your from seeing it get changed externally. Most compilers assume a global variable changes externally and don't need volatile for a global. I will probably get a lot of flack for not being specific about volatile.

You want to ensure the global is zeroed out before your threads run.

Exactly, to the nanosecond, when thread A will see the change is a different issue. If the thread is running concurrently with thread B then it will see it as soon as the change is made. If thread A is asleep it wont see anything. It is even possible thread B can change the flag before thread A starts. When a thread is actually destroyed happens at some indeterminate time after the thread function returns - whenever the OS gets around to it.

like image 36
johnnycrash Avatar answered Oct 06 '22 11:10

johnnycrash