Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kind of Master/Slave locking system?

I have no clue if the thing I want to do has a name or not. The "Master/Slave locking system" is sadly the best wording I could come up with.

Now to the problem I have...

Imagine you have the following class:

public class Foo
{
    public void Master()
    {

    }

    public void Slave1()
    {

    }

    public void Slave2()
    {

    }
}

What I desire is that the slaves methods (Slave1, Slave2) can run parallel in a multi-threading scenario, but when the master (Master) method is called the slaves method shall be blocked from executing while it is executing, additional all currently running slave methods shall run to completion upon entering the master method.

Something like this (with comments):

public class Foo
{
    public void Master()
    {
        //block slaves from executing
        //wait for slaves to finish

        //do code...

        //unblock slaves
    }

    public void Slave1()
    {
        //if blocked by master wait, if not execute
        //if currently running when entering master method, let it finish
    }

    public void Slave2()
    {
        //if blocked by master wait, if not execute
        //if currently running when entering master method, let it finish
    }
}

I know I could use lock on all 3 methods but than the Slave1 methods will block each other and thats not what I desire.

public class Foo
{
    private readonly object _syncLock = new object();

    public void Master()
    {
        lock (_syncLock) //blocks Slave1, Slave2
        {
            //run code...
        }
    }

    public void Slave1()
    {
        lock (_syncLock) //blocks Slave2, Master - dont want that
        {
            //run code...
        }
    }

    public void Slave2()
    {
        lock (_syncLock) //blocks Slave1, Master - dont want that
        {
            //run code...
        }
    }
}

If possible I would like to have the solution inside this class and not some outside "if you call the methods that way it will do it", the mentioned methods can fire at anytime in a non-ordered way and each method can run muliple times.

like image 243
Rand Random Avatar asked Oct 18 '22 19:10

Rand Random


1 Answers

If I understand you right, you want to put

  • Exclusive (Write) lock on Master() (no SlaveN can run)
  • Shared (Read) lock on each Slave (you can run another SlaveN, but not Master)

If it's your case, please, have a look at ReaderWriterLockSlim:

public class Foo {
    private readonly ReaderWriterLockSlim _syncLock = new ReaderWriterLockSlim();

    public void Master() {
      // Exclusive (write) lock: only Master allowed to run
      _syncLock.EnterWriteLock();

      try {
        //run code...
      }
      finally {
        _syncLock.ExitWriteLock();
      }   
    }

    public void Slave1() {
      // Read lock: you can run Slave2 (with another Read lock), but not Master 
      _syncLock.EnterReadLock();

      try {
        //run code...
      }
      finally {
        _syncLock.ExitReadLock();
      }         
    }

    public void Slave2() {
      // Read lock: you can run Slave1 (with another Read lock), but not Master 
      _syncLock.EnterReadLock();

      try {
        //run code...
      }
      finally {
        _syncLock.ExitReadLock();
      }         
    }   
}
like image 94
Dmitry Bychenko Avatar answered Oct 21 '22 01:10

Dmitry Bychenko