Home > Net >  What are the options for safely modifying and reading a boolean across multiple threads and cpus?
What are the options for safely modifying and reading a boolean across multiple threads and cpus?

Time:09-16

I have some C code that contains roughly this logic:

class wrapper_info {
public:
        bool isConnected();
        void connectedHandler();
        void disconnectedHandler();
protected:
        bool _connected;
}

void wrapper_info::connectedHandler() {
        _connected = true;
}

void wrapper_info::disconnectedHandler() {
        _connected = false;
}

bool wrapper_info::isConnected() {
        return _connected;
}

extern "C"
bool is_connected(void *obj) {
        wrapper_info *wrapper_obj = reinterpret_cast<wrapper_info*>(obj);
        return wrapper_obj->isConnected();
}

For reasons mostly out of my control, different threads (running on different CPU cores) call these functions in the following way.

Thread 1, 2, 3: is_connected(obj)

Thread 2: connectedHandler() when the connection is initiated.

Thread 3 disconnectedHandler() when the connection is broken.

I am thinking there could be issues in the event of repeated calls to connectedHandler() and disconnectedHandler(), issues with the two threads writing to _connected and the writes getting out of order, resulting in the wrong final value. And potentially also issues with polling _connected as well.

My questions are:

  1. What potential issues could actually arise from separate threads polling and modifying the value of _connected?
  2. What options are there to prevent these? Perhaps making _connected a volatile bool might solve issues polling the value. I was also thinking for the issue of threads 2 and 3 modifying its value, perhaps making it an atomic bool and using atomic set operations will be sufficient to prevent issues like out-of-order memory operations. I also know other potential solutions are locks or memory barriers like smb_mb. However, I am not sure what I should use.

Thank you lots.

CodePudding user response:

What potential issues could actually arise from separate threads polling and modifying the value of _connected?

It's Undefined Behavior, no matter what.

What options are there to prevent these?

A common solution is to use std::atomic<bool> instead of bool.

There are fancier (and much more complex) ways to ensure synchronization between threads, but std::atomic is an excellent first choice, and not difficult to use correctly.

Perhaps making _connected a volatile bool might solve issues

It won't. volatile does not solve thread synchronization issues.

  • Related