Я читал документацию AutoResetEvent в MSDN, и следующее предупреждение меня беспокоит.
«Важно: нет гарантии, что каждый вызов метода Set освободит поток. Если два вызова слишком близки друг к другу, так что второй вызов происходит до того, как поток будет освобожден, освобождается только один поток. второй вызов не произошел. Кроме того, если Set вызывается, когда нет ожидающих потоков, а AutoResetEvent уже сигнализируется, вызов не имеет никакого эффекта».
Но это предупреждение в основном убивает саму причину использования таких методов синхронизации потоков. Например, у меня есть список, который будет содержать рабочие места. И есть только один производитель, который добавит рабочие места в список. У меня есть потребители (более одного), ожидающие получения задания из списка.. что-то вроде этого..
Продюсер:
void AddJob(Job j)
{
lock(qLock)
{
jobQ.Enqueue(j);
}
newJobEvent.Set(); // newJobEvent is AutoResetEvent
}
Потребитель
void Run()
{
while(canRun)
{
newJobEvent.WaitOne();
IJob job = null;
lock(qLock)
{
job = jobQ.Dequeue();
}
// process job
}
}
Если приведенное выше предупреждение верно, то, если я очень быстро поставлю в очередь два задания, только один поток подхватит задание, не так ли? Я исходил из того, что Set будет атомарным, то есть он делает следующее:
- Установить событие
- Если потоки ожидают, выберите один поток для пробуждения
- сбросить событие
- запустить выбранный поток.
Так что я в основном запутался в предупреждении в MSDN. это действительное предупреждение?