I have a thread that is started and runs continuously upon launch of the program (I'm using pthreads). I need to send commands to the thread from the main thread. I can set a global variable, but that seems risky because what if the secondary thread and main thread try to access it simultaneously? I can wrap the variable in a mutex, but is that necessary? What if I just put in the main thread a button that executes code like this:
// main thread
if(!trigger_variable)
trigger_variable=1;
Then, in the second thread I use this:
// other thread
if(trigger_variable){
do_something();
trigger_variable=0;
}
Would this be robust enough to avoid using a mutex?
CodePudding user response:
A trigger_variable
can work as long as it's an atomic type; for regular/non-atomic types it would invoke undefined behavior, since you'd have two threads reading and writing the same memory without any synchronization.
However, setting a shared variable is not exactly "sending a command" so much as setting a piece of shared state, so I wouldn't call it "bulletproof" for this purpose. For example, if you wanted to send two commands in quick succession, it would be difficult to guarantee that both were received, since the second change to the variable might overwrite the first one before the child thread ever got a chance to see the first value.
If you want to be able to send commands properly (e.g. so that each command is received by the child thread, in the order the commands were sent) one relatively easy way to do it would be have the main thread create a pipe and give the data-reading-file-descriptor of the pipe to the child thread. Then the main thread can write() a byte on the data-writing-file-descriptor whenever it wants the child thread to do something, and the child thread can read() that byte and react appropriately.
CodePudding user response:
According to §5.1.2.4 ¶25 and ¶4 of the official ISO C11 standard, two different threads reading and writing to the same memory location using non-atomic operations in an unordered fashion causes undefined behavior.
However, if you use atomic types instead, or the atomic operations libary, then your plan should work.