代码之家  ›  专栏  ›  技术社区  ›  sebagomez

如何在C中编写条件锁?

  •  7
  • sebagomez  · 技术社区  · 17 年前

    问题是我一直在使用 lock statement 为了保护我的代码的关键部分,但是现在,我意识到我可以允许同时执行关键代码,这是满足一些条件的。
    有办法调节门锁吗?

    7 回复  |  直到 10 年前
        1
  •  5
  •   Amy B    17 年前
    Action doThatThing = someMethod;
    
    if (condition)
    {
      lock(thatThing)
      {
         doThatThing();
      }
    }
    else
    {
      doThatThing();
    }
    
        2
  •  9
  •   Tomalak    17 年前

    我觉得这个问题叫“比赛条件!”。如果在检查后不久,线程进入关键代码段之前,条件从“真”变为“假”,该怎么办?或者当一个线程正在执行它时?

        3
  •  8
  •   user31934    17 年前

    我不是线程专家,但听起来您可能在寻找类似的东西(双重检查锁定)。其思想是在获取锁之前和之后检查条件。

    private static object lockHolder = new object();
    
    if (ActionIsValid()) {
      lock(lockHolder) {
        if (ActionIsValid()) {
           DoSomething();    
        }
      }
    }
    
        4
  •  7
  •   marijne    17 年前
    bool locked = false;
    if (condition) {
        Monitor.Enter(lockObject);
        locked = true;
    }
    try {
        // possibly critical section
    }
    finally {
        if (locked) Monitor.Exit(lockObject);
    }
    

    编辑:是的,有一个争用条件,除非您可以确保在线程进入时条件是恒定的。

        5
  •  4
  •   Marc Gravell    17 年前

    实际上,为了避免比赛条件,我会尝试使用 ReaderWriterLockSlim 这里-将并发访问视为读锁,将独占访问视为写锁。这样一来,如果条件发生了变化,您就不会最终得到一些不适当的代码仍然在该区域盲目执行(在错误的假设下,它是安全的);有点冗长,但是 (格式化为空格):

            if (someCondition) {
                lockObj.EnterReadLock();
                try { Foo(); }
                finally { lockObj.ExitReadLock(); }
            } else {
                lockObj.EnterWriteLock();
                try { Foo(); }
                finally { lockObj.ExitWriteLock(); }
            }
    
        6
  •  2
  •   Pure.Krome    17 年前

    使用 Double-checked locking pattern ,如上所述。这就是我的诀窍:)

    确保将锁定对象作为 静止的 如not.that.dave.foley.myopenid.com中所列。

        7
  •  1
  •   noocyte    17 年前

    我猜你有一些代码看起来有点像这样:

    private Monkey GetScaryMonkey(int numberOfHeads){
        Monkey ape = null;        
        lock(this) {
            ape = new Monkey();
            ape.AddHeads(numberOfHeads);            
        }
        return ape;
    }
    

    要使这成为条件,你不能这样做:

    private Monkey GetScaryMonkey(int numberOfHeads){
        if ( numberOfHeads > 1 ) {
             lock(this) {
                return CreateNewMonkey( numberOfHeads );          
            }
        }
        return CreateNewMonkey( numberOfHeads );
    }
    

    应该工作,不是吗?