Есть ли способ проверить, соответствует ли pid действующему процессу? Я получаю pid из другого источника, кроме from, os.getpid()
и мне нужно проверить, не существует ли на машине процесса с этим pid.
Мне нужно, чтобы он был доступен в Unix и Windows. Я также проверяю, НЕ используется ли PID.
Ответы:
Отправка сигнала 0 в pid вызовет исключение OSError, если pid не запущен, и ничего не сделает в противном случае.
источник
os.kill(pid, 0)
это то же самое,os.kill(pid, signal.CTRL_C_EVENT)
что может завершить процесс (или дать сбой). Я получаюOSError
где,errno==EINVAL
когда пробую это в подпроцессе.Взгляните на
psutil
модуль:У него есть функция,
pid_exists()
которую вы можете использовать, чтобы проверить, существует ли процесс с данным pid.Вот пример:
Для справки:
источник
psutil
реализованоpid_exists()
в POSIX . Сравните с ответом @Giampaolo Rodolà (автораpsutil
)код mluebke неверен на 100%; kill () также может вызывать EPERM (доступ запрещен), и в этом случае это, очевидно, означает, что процесс существует. Это должно работать:
(отредактировано в соответствии с комментариями Джейсона Р. Кумбса)
Вы не можете сделать это в Windows, если не используете pywin32, ctypes или модуль расширения C. Если вас устраивает зависимость от внешней библиотеки, вы можете использовать psutil :
источник
Ответы, включающие отправку «сигнала 0» процессу, будут работать, только если соответствующий процесс принадлежит пользователю, запускающему тест . В противном случае вы получите
OSError
из-за разрешений , даже если pid существует в системе.Чтобы обойти это ограничение, вы можете проверить,
/proc/<pid>
существует ли :Очевидно, это относится только к системам на базе Linux.
источник
PermissionError
означает, что pid существует , вы получите,ProcessLookupError
если pid не существует.OSError
за отказа в разрешении можно отличить от других - либо путем просмотра errno, либо путем перехвата более специализированныхPermissionError
/ProcessLookupError
исключений, которые происходят изOSError
. Более того, вы получите ошибку разрешения, только если процесс существует. Таким образом, ваш пример - это просто альтернативный метод, который работает в Linux и некоторых других Unix, но он не более полон, чем правильный вызовos.kill(pid, 0)
./proc
PROCFS выходит только на Linux, даже не на BSD или OSX.В Python 3.3+ вы можете использовать имена исключений вместо констант errno. Версия Posix :
источник
Поищите здесь способ получения полного списка запущенных процессов с их идентификаторами для Windows. Это было бы что-то вроде
Затем вы можете проверить полученный pid по этому списку. Я понятия не имею о стоимости производительности, поэтому вам лучше проверить это, если вы собираетесь часто выполнять проверку pid.
Для * NIx просто используйте решение mluebke.
источник
Основываясь на ntrrgc, я улучшил версию для Windows, чтобы она проверяла код завершения процесса и проверяла разрешения:
источник
GetExistCodeProcess
требуются права доступаPROCESS_QUERY_INFORMATION
иPROCESS_QUERY_LIMITED_INFORMATION
.GetExitCodeProcess
получает дескриптор и указатель, а в этом примере он получаетExitCodeProcess
структуру в качестве второго параметра, хотя это должен быть только указатель.Объединив ответ Джампаоло Родола для POSIX и мой для Windows, я получил следующее:
источник
GetExitCodeProcess
и убедиться, что у вас есть доступ.kernel32.OpenProcess
недостаточно. Как здесь указано, «если процесс завершился недавно, идентификатор идентификатора может все еще существовать для дескриптора». Еслиkernel32.OpenProcess
возвращается ненулевое значение, нам все равно нужноkernel32.GetExitCodeProcess
дополнительно проверить код выхода.В Windows это можно сделать так:
Прежде всего, в этом коде вы пытаетесь получить дескриптор процесса с заданным pid. Если дескриптор действителен, закройте дескриптор для процесса и верните True; в противном случае вы вернете False. Документация для OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
источник
Это будет работать для Linux, например, если вы хотите проверить, запущена ли banshee ... (banshee - музыкальный проигрыватель)
источник
os.kill(pid, 0)
или просмотром/proc/{pid}
. Вместо выполнения одного системного вызова ваш код разветвляет дочерний элемент, запускает оболочку в этом дочернем элементе, оболочка интерпретирует ваш лишний мини-сценарий оболочки, оболочка создает другой дочерний элемент, который выполняет pgrep, и, наконец, pgrep выполняет итерацию/proc
. Ваш ответ не отвечает на заданный вопрос. OP запросил метод с учетом PID. Вашему методу требуется имя процесса.Следующий код работает как в Linux, так и в Windows, и не зависит от внешних модулей.
Его можно легко улучшить, если вам понадобится
источник
Я бы сказал, используйте PID для любых целей, которые вы его получаете, и аккуратно обрабатывайте ошибки. В противном случае это классическая гонка (PID может быть действительным, когда вы проверяете его действительность, но исчезнет через мгновение)
источник