Why cannot volatile ensure that each thread reads the latest value?

suhoro 0 Reputation points
2024-01-18T05:56:28.67+00:00

The following image is from the official document,but I don't understand.

Can someone help explain it?

appreciateUser's image

Developer technologies C#
{count} votes

2 answers

Sort by: Most helpful
  1. Anonymous
    2024-01-18T07:41:15.2666667+00:00

    Hi @suhoro , Welcome to Microsoft Q&A,

    The main purpose of the volatile keyword is to ensure the consistency and visibility of shared variables in a multi-threaded environment.

    Relative to using locks or other more heavyweight synchronization mechanisms, volatile provides a lightweight way to ensure visibility and consistency between threads. It is a simple and effective option in some situations.

    However, it should be noted that volatile does not solve all thread safety issues, especially when compound operations (such as check-run-write) are involved. In these cases, it may be necessary to use more powerful synchronization mechanisms, such as locks or other concurrency control means.

    This is a special case in the picture. It demonstrates that even if you use Volatile.Write in one thread to write to a shared variable (y), and use Volatile.Read in another thread to read this shared variable, there is still no guarantee that the subsequent Volatile.Read will read another shared variable. (x) will see the updated value. This involves memory visibility issues.

    Specifically, while Volatile.Write ensures that all previous writes in that thread occur before Volatile.Write that follows it, and Volatile.Read ensures that all subsequent reads in that thread occur before its The previous Volatile.Read occurs after each other, but they cannot affect the order between different shared variables.

    In this example, although the Volatile.Write write on thread 1 occurs before the Volatile.Read on thread 2, there is no guarantee that the read of x2 in thread 2 will see the update of the write of x in thread 1. value. Therefore, x2 in thread 2 may still be 0, even though y2 is 1.

    This highlights a limitation of volatile: it only provides atomicity and visibility guarantees for operations on a single shared variable, but not consistency across different shared variables. For more complex operations or dependencies between multiple shared variables, a more powerful synchronization mechanism may be required.

    Best Regards, Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".  Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2024-01-18T21:35:02.14+00:00

    computer CPU use a cache to access memory. if a CPU supports multiple core/processors, each core may has its own cache. also each core has its own instruction pipeline which can reorder instructions.

    for example in these memory location updates:

    1. x=1
    2. y=2
    3. z=x

    the pipeline can do the first two operation in any order and #1 must be done before #3. so the pipeline can do #1,#2,#3 or #1,#3,#2 or #2,#1,#3, it does not matter. but if 2 cores are looking at the values, the order they are assigned may matter. in your code you may depend on y being set before z (even if behind).

    volatile disables the pipeline from reordering instructions. but as 2 threads may be on different cores or processors, they may see different values due to using non-shared cached values. if both cores must always see the same value for y, then you must use interlock instructions which invalidate the cache. see:

    https://en.wikipedia.org/wiki/Cache_coherence

    you must really understand cpu architecture to make use of volatile.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.