Home > Blockchain >  volatile variable updated from multiple threads C
volatile variable updated from multiple threads C

Time:07-23

    volatile bool b;
 
    
    Thread1: //only reads b
    void f1() {
    while (1) {
       if (b) {do something};
       else { do something else};
    }
    }
    
    Thread2: 
    //only sets b to true if certain condition met
    // updated by thread2
    void f2() {
    while (1) {
       //some local condition evaluated - local_cond
       if (!b && (local_cond == true)) b = true;
        //some other work
    }
    }
    
    Thread3:
    //only sets b to false when it gets a message on a socket its listening to
    void f3() {
    while (1) {
        //select socket
        if (expected message came) b = false;
        //do some other work
    }
    }

If thread2 updates b first at time t and later thread3 updates b at time t 5:

will thread1 see the latest value "in time" whenever it is reading b?

for example: reads from t delta to t 5 delta should read true and reads after t 5 delta should read false.

delta is the time for the store of "b" into memory when one of threads 2 or 3 updated it

CodePudding user response:

Will thread1 see the latest value "in time" whenever it is reading b?

Yes, the volatile keyword denotes that it can be modified outside of the thread or hardware without the compiler being aware thus every access (both read and write) will be made through an lvalue expression of volatile-qualified type is considered an observable side effect for the purpose of optimization and is evaluated strictly according to the rules of the abstract machine (that is, all writes are completed at some time before the next sequence point). This means that within a single thread of execution, a volatile access cannot be optimized out or reordered relative to another visible side effect that is separated by a sequence point from the volatile access.

Unfortunately, the volatile keyword is not thread-safe and operation will have to be taken with care, it is recommended to use atomic for this, unless in an embedded or bare-metal scenario.

Also the whole struct should be atomic struct X {int a; volatile bool b;};.

CodePudding user response:

Say I have a system with 2 cores. The first core runs thread 2, the second core runs thread 3.

reads from t delta to t 5 delta should read true and reads after t 5 delta should read false.

Problem is that thread 1 will read at t 10000000 when the kernel decides one of the threads has run long enough and schedules a different thread. So it likely thread1 will not see the change a lot of the time.

Note: this ignores all the additional problems of synchronicity of caches and observability. If the thread isn't even running all of that becomes irrelevant.

  • Related