1

have another confusion about locking in C#.

The problem is sharing a state among diffrent threads.

Following scenario:

A thread processes a state machine. This machine, for example, counts up a value with delay. The machine thread reads this value and increments. Other threads shall now be able to read this count value. Actually I have more values than just a a single count, so I prepared a class which holds the shared values. This looks like this:

IStatus is a suitable private interface. Summaries are removed since not in English.

    public class Status : ICloneable, IStatus
    {
      private object locker;

      public bool Run { get; private set; }

      public uint SecondRemain { get; private set; }

      // ... and some more value types

      public Status()
      {
        locker = new object();
      }
      
      void IStatus.SetRun(bool enable)
      {
        lock (locker)
        {
          Run = enable;
        }
      }
      
      void IStatus.SetSecondRemain (uint value)
      {
        lock (locker)
        {
          SecondRemain = value;
        }
      }

      // ... and some more set of value types

      public object Clone()
      {
        object copy;
        lock (locker)
        {
          copy = MemberwiseClone();

          // Since it is a "new" object, we decouple the lock
          ((Status)copy).locker = new object();
        }
        return copy;
      }

In main class where the state machine and its thread lives in:

private Status shared;

// Shall be accessible by any thread at any time

public Status GetStatus()
{
  // Clones thread-safe, fenced by locker
  return (Status) shared.Clone();
}

// Will be accessed only by inner thread
private void AnyMethodCalledStateMachineThread()
{
  // Get the current remaining second value.
  // No fence here ??
  uint value = shared.SecondRemain;
  
  // fences by locker 
  ((IStatus) shared).SetSecondRemain (value++);
}

What we see now is, only the inner thread will read and write to some values. This thread will read what it has previously written. To ensure other threads can read this, it is locked.

External threads can only get a full copy by lock statement.

But does internal thread itself needs lock, too, when reading single properties or do I have to put lock around these properties (with extra field)?

EDIT

This is the requested sort of code which runs the thread

var thread;

private void Start()
{
  thread = new Thread(new ThreadStart(ProducerMain));
  thread.Start(); 
}

// Example, no real code
private void ProducerMain()
{
  while ( ...)
  {

    Thread.Sleep(1000);

    AnyMethodCalledStateMachineThread();

  }
}
MrV
  • 25
  • 5
  • Can you explain what you mean by *"inner thread"*? AFAIK threads have not outer/inner or parent/child relationship. – Theodor Zoulias Jul 07 '21 at 09:11
  • Yes: the "inner thread" is the thread which is inside the class and controls the statemachine. This thread is the only thread wich will read and write to the Status class Properties – MrV Jul 07 '21 at 09:20
  • *"the thread which is inside the class"* <== do you mean that the class has a field of type `Thread`? – Theodor Zoulias Jul 07 '21 at 09:24
  • Yes this is a possible situation. The main thing is, it is always the same thread wich is changing the values. – MrV Jul 07 '21 at 09:27
  • 1
    The way you describe the concepts of "inner thread", and "thread inside a class" is a bit confusing to me. Would you like to include in the question some (minimal) code that shows how this specific thread is created, and what code is running on this thread? – Theodor Zoulias Jul 07 '21 at 10:28
  • I placed a piece of code as you wished. But actually the way of thread creation or where the thread comes from should not matter. The matter is, that the method AnyMethodCalledStateMachineThread() will be called from this thread and from no other at any time. – MrV Jul 07 '21 at 14:15
  • OK, thanks for adding the thread-related code. Now I noticed something else. In this line: `uint value = shared.SetSecondRemain;` the `SetSecondRemain` is used as a property, although it is a method. – Theodor Zoulias Jul 07 '21 at 14:32

0 Answers0