Safely modifying variables in a multithreaded environment.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Frank Rizzo

    Safely modifying variables in a multithreaded environment.

    Hello,

    I want to use a variable as a signal to the thread that it should stop
    what it's doing (code below). As a rule, should I lock an object only
    when I am writing to it or do I have to lock on reading as well? For
    instance, consider the following code:

    //running in a non-GUI thread
    foreach (object o in objects)
    {
    ...
    if (SignalObject.S topSignalDetect ed) break;
    }


    //running in the GUI thread.
    void btnStop_Click(. ..)
    {
    lock (SignalObject)
    {
    SignalObject.St opSignalDetecte d = true;
    }
    }

    Is SignalObject.St opSignalDetecte d safe here? Or should I lock it in
    the non-GUI thread as well, even though it will only read it?

    Thanks
  • Jon Skeet [C# MVP]

    #2
    Re: Safely modifying variables in a multithreaded environment.

    Frank Rizzo <none@none.co m> wrote:[color=blue]
    > I want to use a variable as a signal to the thread that it should stop
    > what it's doing (code below). As a rule, should I lock an object only
    > when I am writing to it or do I have to lock on reading as well?[/color]

    In general, you need to lock for reading as well, for two reasons:

    1) To pick up changes in writing threads atomically
    2) To guarantee that pick up changes in writing threads at all

    See http://www.pobox.com/~skeet/csharp/t...latility.shtml

    --
    Jon Skeet - <skeet@pobox.co m>
    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    If replying to the group, please do not mail me too

    Comment

    • Mark R. Dawson

      #3
      RE: Safely modifying variables in a multithreaded environment.

      Usually when you have a number of operations to carry out as one logical unit
      that require reading and writing then you should lock the variable, for
      example:

      Company A requests person A's bank balance (it's $100)
      Company B requests person A's bank balance (it's $100)
      Company A adds $100 -> total is $200 (because it read $100)
      Company B debits $25 -> total is $75 (because it read $100)
      Company A saves the value $200 to user A's account
      Company B saves the value $75 to user A's account

      At the end of the day person A only has $75 in his account instead of $175.

      We had one logical unit of work but it took many steps, so for the bank
      account which here is a resource that is being competed for we need to lock
      so only one thread can access the rsource at any time.

      In your case I am guessing SignalObject.St opSignalDetecte d is just assigning
      to a variable or returning a boolean internally, so there are not a number of
      steps so you really don't need to lock this variable.

      Hope that helps
      Mark.

      "Frank Rizzo" wrote:
      [color=blue]
      > Hello,
      >
      > I want to use a variable as a signal to the thread that it should stop
      > what it's doing (code below). As a rule, should I lock an object only
      > when I am writing to it or do I have to lock on reading as well? For
      > instance, consider the following code:
      >
      > //running in a non-GUI thread
      > foreach (object o in objects)
      > {
      > ...
      > if (SignalObject.S topSignalDetect ed) break;
      > }
      >
      >
      > //running in the GUI thread.
      > void btnStop_Click(. ..)
      > {
      > lock (SignalObject)
      > {
      > SignalObject.St opSignalDetecte d = true;
      > }
      > }
      >
      > Is SignalObject.St opSignalDetecte d safe here? Or should I lock it in
      > the non-GUI thread as well, even though it will only read it?
      >
      > Thanks
      >[/color]

      Comment

      • Frank Rizzo

        #4
        Re: Safely modifying variables in a multithreaded environment.

        Jon Skeet [C# MVP] wrote:[color=blue]
        > Frank Rizzo <none@none.co m> wrote:
        >[color=green]
        >>I want to use a variable as a signal to the thread that it should stop
        >>what it's doing (code below). As a rule, should I lock an object only
        >>when I am writing to it or do I have to lock on reading as well?[/color]
        >
        >
        > In general, you need to lock for reading as well, for two reasons:
        >
        > 1) To pick up changes in writing threads atomically[/color]

        Jon, great link. I learned a lot. And your article is correct: there is
        quite a bit of a performance hit in my app if I lock on reading and
        writing. One quick question though. If I just lock on writing and
        don't care whether the reading thread reads it the first time (second or
        third time is fine), am I ok?
        [color=blue]
        > 2) To guarantee that pick up changes in writing threads at all
        >
        > See http://www.pobox.com/~skeet/csharp/t...latility.shtml
        >[/color]

        Comment

        • Jon Skeet [C# MVP]

          #5
          Re: Safely modifying variables in a multithreaded environment.

          Frank Rizzo <none@none.co m> wrote:[color=blue][color=green]
          > > In general, you need to lock for reading as well, for two reasons:
          > >
          > > 1) To pick up changes in writing threads atomically[/color]
          >
          > Jon, great link. I learned a lot. And your article is correct: there is
          > quite a bit of a performance hit in my app if I lock on reading and
          > writing.[/color]

          Is there? Is it truly significant? I believe in *most* real-world cases
          the hit isn't worth worrying about. A test case which does nothing but
          read and write with multiple threads might have problems, but a real
          app which is doing other things won't have problems - usually! It
          depends on what the app is doing, of course.
          [color=blue]
          > One quick question though. If I just lock on writing and
          > don't care whether the reading thread reads it the first time (second or
          > third time is fine), am I ok?[/color]

          Well, it's not just a case of "second or third time" - it's whether the
          reading thread *ever* sees the change. That isn't guaranteed, although
          to be honest if you call other methods (which aren't inlined) I believe
          there's a memory barrier at that point.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          Working...