0

我正在多线程环境中实现一个抢占式独占函数,如果即使函数没有运行也发生取消请求,当函数运行时,它知道这个取消请求并且不会运行。我在 C# 中使用 ManualResetEvent 等遇到了各种不同的方法来执行此操作(类似于此问题的答案Synchronizing a Timers.Timer elapsed method when stopping),但是我想知道是否像我在下面的代码就足够了。我在这里介绍了任何无意的错误吗?

bool cancel = false;
bool running = false;
object Lock = new object();
void PremptiveExclusiveFunction() {
  lock(Lock) {
    if(running)
      return;
    running = true;
  }

  for(int i=0; i < numIter; i++) {
    lock(Lock) {
      if(cancel) {
       cancel = false;
       running = false;
       return;
      }
    }

    // iteration code
  }

  lock(Lock) {
   running = false;
  } 
}

void Stop() {
  lock(Lock) {
    cancel = true;
  }
}

据我所知,这似乎可以满足我的 3 个要求:
1. 抢占能力
2. 及时排他性,这个函数的唯一副本可以运行
3. 取消请求不会丢失,因为在 PreemptiveExclusiveFunction 之前调用了 Stop

如果我确实遗漏了什么,如果更有经验的人能指出我将不胜感激。

4

1 回答 1

0

可以锁定整个函数体以消除running布尔值:

object @lock = new object();

volatile bool cancel = false;

void Function () {
    if (!Monitor.TryEnter(@lock))
        return;
    try {

        for (var i = 0; i < 100; i++) {
            if (cancel) {
                cancel = false;
                return;
            }

            // code
        }

    } finally {
        Monitor.Exit(@lock);
    }
}

void Stop () {
    cancel = true;
}

+ 注意volatile关键字: http:
//msdn.microsoft.com/en-us/library/vstudio/x13ttww7 (v=vs.100).aspx

于 2013-08-09T06:10:24.570 回答