Why is volatile not considered useful in multithreaded C or C++ programming?

前端 未结 9 2047
予麋鹿
予麋鹿 2020-11-21 21:01

As demonstrated in this answer I recently posted, I seem to be confused about the utility (or lack thereof) of volatile in multi-threaded programming contexts.<

9条回答
  •  北恋
    北恋 (楼主)
    2020-11-21 21:10

    volatile is useful (albeit insufficient) for implementing the basic construct of a spinlock mutex, but once you have that (or something superior), you don't need another volatile.

    The typical way of multithreaded programming is not to protect every shared variable at the machine level, but rather to introduce guard variables which guide program flow. Instead of volatile bool my_shared_flag; you should have

    pthread_mutex_t flag_guard_mutex; // contains something volatile
    bool my_shared_flag;
    

    Not only does this encapsulate the "hard part," it's fundamentally necessary: C does not include atomic operations necessary to implement a mutex; it only has volatile to make extra guarantees about ordinary operations.

    Now you have something like this:

    pthread_mutex_lock( &flag_guard_mutex );
    my_local_state = my_shared_flag; // critical section
    pthread_mutex_unlock( &flag_guard_mutex );
    
    pthread_mutex_lock( &flag_guard_mutex ); // may alter my_shared_flag
    my_shared_flag = ! my_shared_flag; // critical section
    pthread_mutex_unlock( &flag_guard_mutex );
    

    my_shared_flag does not need to be volatile, despite being uncacheable, because

    1. Another thread has access to it.
    2. Meaning a reference to it must have been taken sometime (with the & operator).
      • (Or a reference was taken to a containing structure)
    3. pthread_mutex_lock is a library function.
    4. Meaning the compiler can't tell if pthread_mutex_lock somehow acquires that reference.
    5. Meaning the compiler must assume that pthread_mutex_lock modifes the shared flag!
    6. So the variable must be reloaded from memory. volatile, while meaningful in this context, is extraneous.

提交回复
热议问题