那种主/从锁定系统?

时间:2017-01-11 08:03:50

标签: c# multithreading

我不知道我想要做的事情是否有名字。 令人遗憾的是,“主/从锁定系统”是我能想到的最好的措辞。

现在我遇到的问题......

想象一下,你有以下课程:

public class Foo
{
    public void Master()
    {

    }

    public void Slave1()
    {

    }

    public void Slave2()
    {

    }
}

我想要的是从属方法(Slave1,Slave2)可以在多线程场景中并行运行,但是当调用master(Master)方法时,Slaves方法应该在执行时阻止执行,另外当进入主方法时,所有当前运行的从属方法都将运行完毕。

像这样(带评论):

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
    }
}

我知道我可以对所有3种方法使用锁定,但Slave1方法会阻塞对方,而这不是我想要的。

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...
        }
    }
}

如果可能的话,我希望在这个类中有解决方案,而不是外部的“如果你按照它的方式调用方法”,所提到的方法可以随时以非有序的方式触发,每个方法都可以运行多次。

1 个答案:

答案 0 :(得分:2)

如果我理解你,你想要

  • Master()上的独占(写入)锁定(无SlaveN可以运行)
  • 每个Slave上的共享(阅读)锁定(您可以运行另一个SlaveN,但不能运行Master

如果是您的情况,请查看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();
      }         
    }   
}