私はこのように実装されたタスクスケジューラを持っています:
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