离开 WaitOne 时获取锁定
本文关键字:锁定 获取 WaitOne 离开 | 更新日期: 2023-09-27 18:32:07
我有一个像这样实现的任务调度程序:
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)"之间的所有剩余任务,则存在竞争条件。
离开 mNoTaskEvent.WaitOne() 时,我怎样才能原子地获取 mTasks 锁?
编辑pthread API 有一个函数,可以完全满足我的需要: pthread_cond_wait
竞争条件的简单解决方法是再次检查计数:
lock (mTasks)
{
if (mTasks.Count < 1)
continue;
mTasks.Sort(...);
nextTask = mTasks.First();
}
使用 Monitor.Wait():
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()。