首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >离开WaitOne时获取锁

离开WaitOne时获取锁
EN

Stack Overflow用户
提问于 2012-04-23 08:42:35
回答 1查看 1.1K关注 0票数 1

我有一个像这样实现的任务调度程序:

代码语言:javascript
复制
  private readonly List<Task> mTasks = new List<Task>();
  private readonly ManualResetEvent mNoTaskEvent = new ManualResetEvent(false);

  public void AddTask(Task task)
  {
     lock (mTasks)
     {
        mTasks.Add(task);
        mNoTaskEvent.Set();
     }
  }

  public void RemoveTask(Task task)
  {
     lock (mTasks)
     {
        mTasks.Remove(task);
        if (mTasks.Count == 0)
           mNoTaskEvent.Reset();
     }
  }

  void BackgroundThreadProc()
  {
     while (mRunning)
     {
        mNoTaskEvent.WaitOne();

        if (!mRunning) break;

        Task nextTask;

        lock (mTasks)
        {
           mTasks.Sort(...);
           nextTask = mTasks.First();
        }

        nextTask.Run();
     }
  }

mNoTaskEvent允许在没有可用任务时阻塞后台线程。如果另一个线程删除"mNoTaskEvent.WaitOne()“和"lock (mTasks)”之间的所有剩余任务,则存在争用条件。

离开mTasks ()时,我如何原子地获取mNoTaskEvent.WaitOne锁?

编辑( pthread )有一个函数,它完全满足我的需要:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-23 08:47:50

对于竞赛条件,一个简单的解决办法是再次检查计数:

代码语言:javascript
复制
    lock (mTasks)
    {
       if (mTasks.Count < 1)
         continue;

       mTasks.Sort(...);
       nextTask = mTasks.First();
    }

使用Monitor.Wait():

代码语言:javascript
复制
 while (mRunning)
 {
    //mNoTaskEvent.WaitOne();

    if (!mRunning) break;

    Task nextTask;

    lock (mTasks)
    {
        while (mTasks.Count < 1)
        {
           Monitor.Wait(mTasks);

           if (!mRunning) break;                
        }

        ...     
    }



public void AddTask(Task task)
{
  lock (mTasks)
  {
     mTasks.Add(task);
     //mNoTaskEvent.Set();
     Monitor.Pulse(mTasks);
  }
}

在停止整个链时,还需要Pulse()。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10277336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档