После некоторого этапа тестирования моего планировщика задач я столкнулся с тупиком довольно случайным образом. Я хочу попросить некоторую помощь, особенно я хочу знать, может ли мой подход зайти в тупик или проблема в другом месте.
Прежде чем начать, я скажу, что приложение представляет собой полноэкранную игру. (в случае, если это может повлиять на что-либо)
Я объясню словами, как работает система.Тупик, некоторые вопросы
Задача планировщика
1) Расписание 2 на CPU задач в начале каждого кадра. (по планированию я имею в виду установку частного WaitHandle задачи для установки, позволяющую задаче выполнить некоторую работу)
Вот короткий код, который суммирует, что система делает с каждой из двух задач.
Scheduled++;
InternalLock.Reset();
После того, как все две задачи запланированы, они начинаются с установки частного WaitHandle.
2) Подождите, пока все задачи будут выполнены. Ожидание выполняется, ожидая, что внутренний WaitHandle будет сигнализирован о каждой задаче. (WaitOne() на каждой задаче)
Вот код ожидания:
if (Attese.Length > 0)
{
TmpIsSucceded = false;
for (int i = 0; i < Attese.Length; i++)
{
WaitHandle actual = Attese[i].Wait;
do
{
TmpIsSucceded = actual.WaitOne(150);
if (!TmpIsSucceded)
EnginesManager.ProcessMessages();
} while (!TmpIsSucceded);
}
}
Задача
1) никогда не закрывается до конца игры.
2) Имеет 2 внутренних WaitHandle. Один частный, который рассказывает задачу, когда есть работа для него. Один внутренний, который сигнализируется, когда задача завершила свою работу. (тот, который ожидает планировщик задач)
3) Когда задача сама по себе запускает другую задачу, доступную в синхронизированной (по блокировке()) очереди планировщика задач (таким же образом, устанавливая приватную waithandle этой задачи).
это основной цикл задачи:
private void CoreThread()
{
while (_active)
{
PrivateLock.WaitOne(-1, false);
while (Scheduled > 0)
{
if (OnThreadExecute != null)
OnThreadExecute(this, null);
Scheduled--;
if (Scheduled == 0)
{
PrivateLock.Reset();
if (OnThreadEnd != null)
OnThreadEnd(this, null);
InternalLock.Set();
}
}
}
}
InternalLock и PrivateLock являются двумя waitHandles. Обратите внимание на то, что функция waistandle InternalLock установлена только в этом коде. НЕТ ДРУГОГО МЕСТА, где установлены InternalLock или PrivateLock. (за исключением кода, который я опубликовал)
Когда возникает тупик, планировщик задач ждет выполнения всех задач, но одна из задач никогда не устанавливает waithandle InternalLock. «Заблокированная» задача останавливается на «PrivateLock.WaitOne (-1, false)»; когда происходит тупик.
Кто-нибудь подскажет об этом тупике?
Edit:
internal void StartSchedule()
{
for (int i = 0; i < Tasks.Length; i++)
{
if (Tasks[i].Schedule())
QTasks.Enqueue(Tasks[i]);
}
StartThreadAvailable();
}
private void StartThreadAvailable()
{
TempExecList.Clear();
for (int i = 0; i < NThread; i++)
{
if (QTasks.Count > 0)
TempExecList.Add(QTasks.Dequeue());
}
Int32 count = TempExecList.Count;
for (int i = 0; i < count; i++)
TempExecList[i].StartThread();
}
internal void StartThread()
{
PrivateLock.Set();
}
вот код, где Set() Частного ручки называется спросил.
Schedule() return всегда истинно в этом случае.(Это только добавить 1 к запланированной переменной задачи и сброса InternalLock)
EDIT 2:
Вот код из 2-х классов, спросил:
http://pastebin.com/m225f839e (GameTask)
http://pastebin.com/m389629cd (TaskScheduler)
Пожалуйста, покажите код, который содержит 'PrivateLock.Set() ' –
Добавил код, заданный – feal87
, как вы объявили дескрипторы ожидания? можете ли вы опубликовать полный компиляционный образец? –