volatile member variable with Interlocked

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mark Salsbery [MVP]

    volatile member variable with Interlocked

    I have an member variable (int) that is accessed by multiple threads using
    Interlocked.Inc rement(), Interlocked.Dec rement(), and read directly.

    Using volatile gives me "CS0420: a reference to a volatile field will not be
    treated as volatile" warnings when using the Interlocked functions, which I
    can easily disable with "#pragma warning disable 420".

    Should this variable be marked volatile? Is volatile necessary in this
    case?

    Thanks!
    Mark

    --
    Mark Salsbery
    Microsoft MVP - Visual C++


  • Jeroen Mostert

    #2
    Re: volatile member variable with Interlocked

    Mark Salsbery [MVP] wrote:
    I have an member variable (int) that is accessed by multiple threads
    using Interlocked.Inc rement(), Interlocked.Dec rement(), and read directly.
    >
    Using volatile gives me "CS0420: a reference to a volatile field will
    not be treated as volatile" warnings when using the Interlocked
    functions, which I can easily disable with "#pragma warning disable 420".
    >
    Annoying, isn't it? They should have built in an exception for the
    Interlocked functions.

    One way to avoid it without disabling it is to remove the volatile qualifier
    and explicitly use Thread.Volatile Read() instead. This might be less
    intuitive and easier to get wrong than relying on volatile, though. Then
    again, just using interlocked fields is less intuitive than using monitors. :-)
    Should this variable be marked volatile? Is volatile necessary in this
    case?
    >
    In all likelihood, yes. You've got atomic reads and writes covered, but if
    you don't use volatile, the compiler is free to "optimize" access in the
    threads that read the value. This means there could be an arbitrary delay
    between the interlocked updates and the reader(s) seeing them (technically
    it's even legal if things are optimized in such a way that the readers
    *never* see the updates, but I've never seen the compiler produce code like
    that).

    --
    J.

    Comment

    • Mark Salsbery [MVP]

      #3
      Re: volatile member variable with Interlocked

      "Jeroen Mostert" <jmostert@xs4al l.nlwrote in message
      news:490417e6$0 $200$e4fe514c@n ews.xs4all.nl.. .
      One way to avoid it without disabling it is to remove the volatile
      qualifier and explicitly use Thread.Volatile Read() instead.

      Thread.Volatile Read() ! That's what I was looking for - I hadn't seen that
      before.

      Sure, I could use lock/Monitor but it's a relatively heavyweight solution
      for incrementing/decrementing an integer atomically.

      I realize this has been discussed many times here before - I guess I used
      the wrong search keywords last time.

      From everything I can find, it seems Interlocked accesses the variable with
      volatile semantics - I was just missing a way to read the variable the same
      way.

      Thank you Jeroen!

      Cheers,
      Mark

      --
      Mark Salsbery
      Microsoft MVP - Visual C++



      Comment

      • Jeroen Mostert

        #4
        Re: volatile member variable with Interlocked

        Mark Salsbery [MVP] wrote:
        Sure, I could use lock/Monitor but it's a relatively heavyweight
        solution for incrementing/decrementing an integer atomically.
        >
        Look at it the other way around: *not* using monitors is an optimization,
        and like all optimizations probably not something you should use from the
        get-go until you can show that you need it.

        Multithreading is hard enough, once you abandon monitors and use primitives
        directly it *really* gets hard. Before you know it you're getting a headache
        reading twelve-page threads on memory models and wondering whether this read
        over here really is safe on an Itanium.

        That's my experience, at least -- my respect goes out to all the people who
        have no trouble applying these things in their daily job. I'm holding out
        for better library support. :-)

        --
        J.

        Comment

        • Jon Skeet [C# MVP]

          #5
          Re: volatile member variable with Interlocked

          On Oct 27, 6:23 pm, Jeroen Mostert <jmost...@xs4al l.nlwrote:
          Mark Salsbery [MVP] wrote:
          Sure, I could use lock/Monitor but it's a relatively heavyweight
          solution for incrementing/decrementing an integer atomically.
          >
          Look at it the other way around: *not* using monitors is an optimization,
          and like all optimizations probably not something you should use from the
          get-go until you can show that you need it.
          >
          Multithreading is hard enough, once you abandon monitors and use primitives
          directly it *really* gets hard. Before you know it you're getting a headache
          reading twelve-page threads on memory models and wondering whether this read
          over here really is safe on an Itanium.
          >
          That's my experience, at least -- my respect goes out to all the people who
          have no trouble applying these things in their daily job. I'm holding out
          for better library support. :-)
          That's pretty much exactly what I'd say, too.

          Another way of doing an atomic read is with
          int y = Interlocked.Com pareExchange(re f x, 0, 0)
          which will basically read and conditionally exchange with the same
          value.

          Jon

          Comment

          • Mark Salsbery [MVP]

            #6
            Re: volatile member variable with Interlocked


            "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
            news:d352f23a-fdd7-4f78-9060-31482fa264e5@u2 8g2000hsc.googl egroups.com...
            On Oct 27, 6:23 pm, Jeroen Mostert <jmost...@xs4al l.nlwrote:
            Another way of doing an atomic read is with
            int y = Interlocked.Com pareExchange(re f x, 0, 0)
            which will basically read and conditionally exchange with the same
            value.

            Thanks Jon.

            Mark

            --
            Mark Salsbery
            Microsoft MVP - Visual C++

            >
            Jon

            Comment

            Working...