Volatile and CreateThread

前端 未结 6 456
借酒劲吻你
借酒劲吻你 2020-12-06 07:52

I just asked a question involving volatile: volatile array c++

However my question spawned a discussion on what volatile does.

Some claim that w

6条回答
  •  死守一世寂寞
    2020-12-06 08:36

    Compiling on linux, g++ 4.1.2, I put in the equivalent of your example:

    #include 
    
    bool done = false;
    
    void* thread_func(void*r) {
      while(!done) {};
      return NULL;
    }
    
    void* write_thread_func(void*r) {
      done = true;
      return NULL;
    }
    
    
    int main() {
      pthread_t t1,t2;
      pthread_create(&t1, NULL, thread_func, NULL);
      pthread_create(&t2, NULL, write_thread_func, NULL);
      pthread_join(t1, NULL);
      pthread_join(t2, NULL);
    }
    

    When compiled with -O3, the compiler cached the value, so it checked once and then enters an infinite loop if it wasn't done the first time.

    However, then I changed the program to the following:

    #include 
    
    bool done = false;
    pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
    
    void* thread_func(void*r) {
      pthread_mutex_lock(&mu);
      while(!done) {
        pthread_mutex_unlock(&mu);
        pthread_mutex_lock(&mu);
      };
      pthread_mutex_unlock(&mu);
      return NULL;
    }
    
    void* write_thread_func(void*r) {
    
      pthread_mutex_lock(&mu);
      done = true;
      pthread_mutex_unlock(&mu);
      return NULL;
    }
    
    
    int main() {
      pthread_t t1,t2;
      pthread_create(&t1, NULL, thread_func, NULL);
      pthread_create(&t2, NULL, write_thread_func, NULL);
      pthread_join(t1, NULL);
      pthread_join(t2, NULL);
    }
    

    While this is still a spin (it just repeatedly locks/unlocks the mutex), the compiler changed the call to always check the value of done after the return from pthread_mutex_unlock, causing it to work properly.

    Further tests show that calling any external function appears to cause it to re-examine the variable.

提交回复
热议问题