Как отслеживать наличие работающего приложения в Windows?

У меня есть приложение мастер, которое запускает несколько дочерних приложений (копий самого себя, но с другим ключом в коммандной строке). Во время работы, дочерние приложения выполняют некую работу и мастер-приложение собирает и аггрегирует их результаты. Если приложение мастер закрывается штатно, то оно останавливает все дочерние приложения. Но, иногда, мастер закрывается нештатно (например, падает, или убивается из диспетчера задач). В таком случае, все дочерние приложения продолжают работать .. приходится их завершать вручную.

Варианты, что приходят на ум:

  • регулярно передавать из мастера сообщения дочерним приложениям. Если сообщение не пришло - мастера нет и надо закрываться. Такой вариант не подходит, т.к. мастер может подвиснуть на время обработки данных или быть приостановлен в отладчике.
  • создавать из мастера мютекс с меткой времени. Дочерними проверять, если свежего мютекса нет - мастера нет и надо закрываться. Но не будет ли расточительным, создавать по мютексу раз в 5сек на протяжении часа, например?
  • передавать в дочерние приложения некий идентификатор процесса мастера и проверять его наличие? Не имя, т.к. оно у всех общее, а что-то еще? Как это сделать?
  • как-то еще?

Какой способ правильнее и оптимальнее?
Как можно из дочерних приложений отслеживать, что приложение-мастер закрылось?


Ответы (1 шт):

Автор решения: Kromster

Итак, благодаря помощи zed, получилось сделать.

В мастере пишем:

// GUID сгенерирован случайным образом (Ctrl+Shift+G)
CreateMutex(nil, True, PChar('{D7576A9B-F93C-4F81-9555-6AD8D34E8972}'));

В дочерних добавляем:

TThread.CreateAnonymousThread(
  procedure
  var
    h: Cardinal;
  begin
    h := OpenMutex(MUTEX_ALL_ACCESS, False, PChar('{D7576A9B-F93C-4F81-9555-6AD8D34E8972}'));
    WaitForSingleObject(h, INFINITE);
    Halt;
  end).Start;

Теперь при закрытии мастера, по любой причине, дочерние приложения тоже само-закрываются. Да, Halt это очень грубое закрытие, но для прототипа - сойдет.

→ Ссылка