Что нового

Процессы Временная блокировка повторного использования идентификатора процесса

Oki

Продвинутый
Сообщения
452
Репутация
63
Множество возможных идентификаторов (PID), назначаемыех Windows процессам, довольно невелико, так что возможны, независимо от алгоритма, по которому PID выделяются, повторные использования для новых процессов освободившихся PID от завершённых. В связи с этим возникает вопрос, как предотвратить такое переиспользование в периоды времени, в которые скрипт всё ещё обрабатывает некоторый устаревший PID. Например, вот такой скрипт случайно может завершить не тот процесс, который имелся в виду.
Код:
$aProcessList = ProcessList("AutoIt3.exe")
For $i = 1 To $aProcessList[0][0]
   ProcessClose($aProcessList[$i][1])
Next
Не использовать PID именно для этой узкой задачи не предлагайте, этот скрипт приведён только для демонстрации проблемы в общем.
Сообщение автоматически объединено:

Была у меня мысль отказаться от блокировки для целей обработки, вместо чего проверять по времени начала процесса, но это не даёт абсолютного решения проблемы, а лишь позволяет уменьшить вероятность возникновения ошибочной обработки не того процесса, всё ещё не обнуляя эту вероятность.
 
Последнее редактирование:

Norm

Продвинутый
Сообщения
291
Репутация
76
Может создать список сохраняемый в файл и туда записывать PID от запускаемых скриптов, а по завершении скрипта обнулять его.
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
63

Norm

Это не поможет. Оказывается, проблема эта настолько глобальна, что даже на сайте Microsoft её игнорируют.

Process.Id Свойство

Редакторы сайта умудрились на одной этой страничке одновременно как обратить внимание на то, что "Идентификаторы процессов могут использоваться системой повторно", так и проигнорировать это в собственном коде, в котором не предусматривают вероятность такой ситуации в промежутке между выполнением строк "Process[] localByName = Process.GetProcessesByName("notepad");" и "chosen.Kill();", в течение которого может пройти довольно много времени, поскольку в этот промежуток времени предусмотрена остановка на пользовательский ввод, а за неограниченное время вполне вероятна ситуация, что какой-то работающий скрипт или иной фактор завершит этот процесс и запустит новый с таким же названием, случайно получающий тот же идентификатор процесса. Проверкой времени начала процесса непосредственно перед обработкой эту вероятность хотя бы можно сильно уменьшить, уповая на то, что интервал времени для такого сбоя станет очень маленьким, но даже с введением такой проверки надёжность всё ещё не станет полной.
 
Последнее редактирование:

Norm

Продвинутый
Сообщения
291
Репутация
76
Все равно не понятно, почему это не поможет.
Если PID уже вписан, то значит его трогать, не завершать, а если его в списке нет, то это не скрипт.
Если кокой-то из криптов был завершён, то только эту запись удалить.
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
63

Norm

Это вообще не о том. При чём тут наш скрипт, в котором мы собираемся завершить процесс? Процессы создаются и завершаются и без его предписаний. За своими действиями следить не проблема.
 

Prog

Продвинутый
Сообщения
597
Репутация
77
Это не поможет. Оказывается, проблема эта настолько глобальна, что даже на сайте Microsoft её игнорируют.
Да, и она не только с процессами.
Любой номер освободившегося объекта (хендл файла, дескриптор окна или контрола и т. д.) может быть использован повторно. https://autoit-script.ru/threads/neskolko-neponjatnyx-momentov-v-rabote-autoita.28712/post-157575
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
63

Prog

А это тут при чём? Дескриптор окна или файла может посторонняя программа увести? Нет же.
Сообщение автоматически объединено:

А давайте вы сначала вдумчиво прочитаете, о чём идёт речь, прежде чем отвечать невпопад? Вдумайтесь в то, как приведённый в стартовом посте скрипт может привести к непредвиденному результату и по каким причинам.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
597
Репутация
77
как приведённый в стартовом посте скрипт может привести к непредвиденному результату
Вероятность этого минимальна. Получение списка процессов и их закрытие занимает немного времени (меньше секунды). Маловероятно что после вызова ProcessList() и перед вызовом ProcessClose() процесс успеет завершится и будет запущен другой процесс с тем же PID.
Другое дело если между получением списка и работой с PID проходит много времени (минуты, часы или больше).
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
63
Вероятность этого минимальна.
Вот только последствия могут оказаться очень неприятными. А при многократном использовании вероятность начинает ещё и расти, увеличиваясь по закону больших чисел до очень нехороших значений. Кстати, в более практичной, чем мой приведённый для примера короткий скрипт, программе на C# с сайта Microsoft, если не дошли руки взглянуть или разобраться, такая пауза не столь коротка, а они это игнорируют это вопреки собственным словам на той же странице, в которых прямо говорится о таком риске.

Повторяю, что я осознаю: уменьшить вероятность такого сбоя можно проверкой времени начала процесса непосредственно перед моментом инструкции о завершении процесса, благо существует функция _WinAPI_GetProcessTimes(). Уменьшить, но не обнулить. В этом топике поднят вопрос о том, можно ли сделать работу корректной без вероятности столь неприятного сбоя при работе "на авось". Чтобы не было необходимости в скрипт вставлять остановку с предупреждением о том, чтобы пользователь подготовился к тому, что в ближайшие секунды может произойти сбой, который приведёт к невосполнимым потерям.
 
Последнее редактирование:
Верх