Proc get status: примеры (PHP)
proc_get_status(resource $process): arrayФункция proc_get_status() возвращает информацию о процессе, запущенном через функцию proc_open(). Она используется для мониторинга состояния внешнего процесса во время его выполнения.
Эта функция применяется для получения текущего статуса дочернего процесса: работает ли он, завершился ли, код возврата. Это полезно при создании скриптов, которым нужно взаимодействовать с длительными внешними командами.
Функция принимает один обязательный параметр:
- $process — ресурс, возвращаемый функцией proc_open(), который представляет запущенный процесс.
Возвращает ассоциативный массив со статусом или false в случае ошибки.
$descriptors = [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"]
];
$process = proc_open('sleep 2', $descriptors, $pipes);
if (is_resource($process)) {
sleep(1); // Ждем 1 секунду
$status = proc_get_status($process);
echo "Запущен: " . ($status['running'] ? 'Да' : 'Нет') . "\n";
echo "PID: " . $status['pid'] . "\n";
echo "Код выхода: " . $status['exitcode'] . "\n";
proc_close($process);
}Запущен: Да PID: 12345 Код выхода: -1
$process = proc_open('ls -la', $descriptors, $pipes);
while (true) {
$status = proc_get_status($process);
if (!$status['running']) {
echo "Процесс завершился с кодом: " . $status['exitcode'] . "\n";
break;
}
usleep(100000); // Проверяем каждые 0.1 секунды
}Процесс завершился с кодом: 0
Выполняет команду через shell и возвращает вывод как строку. Подходит для простых команд, где не требуется контроль над процессом.
Выполняет внешнюю программу и возвращает последнюю строку вывода. Позволяет получить код возврата через третий параметр.
Открывает процесс как файловый указатель для чтения или записи. Проще в использовании для однонаправленного взаимодействия.
Создает дочерний процесс (требует модуль PCNTL). Предоставляет полный контроль над процессами, но сложнее в использовании.
proc_get_status() предпочтительнее, когда необходим детальный контроль и мониторинг состояния процесса во время его выполнения.
import subprocess
proc = subprocess.Popen(['sleep', '2'])
print(f"Запущен: {proc.poll() is None}")
proc.wait()
print(f"Код возврата: {proc.returncode}")Запущен: True Код возврата: 0
const { spawn } = require('child_process');
const ls = spawn('ls', ['-la']);
console.log(`PID: ${ls.pid}`);
ls.on('close', (code) => {
console.log(`Код выхода: ${code}`);
});sleep 5 &
pid=$!
echo "PID: $pid"
if kill -0 $pid 2>/dev/null; then
echo "Процесс работает"
else
echo "Процесс завершен"
fi$status = proc_get_status('не ресурс');
var_dump($status);Warning: proc_get_status() expects parameter 1 to be resource, string given bool(false)
$process = proc_open('ls', $descriptors, $pipes);
proc_close($process);
$status = proc_get_status($process);
var_dump($status);Warning: proc_get_status(): supplied resource is not a valid process resource bool(false)
$process = proc_open('echo test', $descriptors, $pipes);
$status1 = proc_get_status($process);
proc_close($process);
$status2 = proc_get_status($process); // ОшибкаВ PHP 8.0 функция была сделана более строгой к типам передаваемых аргументов. В случае передачи некорректного типа данных теперь выбрасывается TypeError вместо предупреждения.
// В PHP 7.4
proc_get_status('string'); // Warning, возвращает false
// В PHP 8.0+
proc_get_status('string'); // TypeErrorВ PHP 8.1 добавлена статическая проверка типов при передаче ресурсов.
$processes = [];
for ($i = 0; $i < 3; $i++) {
$processes[$i] = proc_open("sleep " . ($i+1), $descriptors, $pipes);
}
while (!empty($processes)) {
foreach ($processes as $i => $process) {
$status = proc_get_status($process);
if (!$status['running']) {
echo "Процесс $i завершен с кодом: " . $status['exitcode'] . "\n";
proc_close($process);
unset($processes[$i]);
}
}
usleep(100000);
}$process = proc_open('trap "echo SIGTERM received; exit 1" SIGTERM; sleep 10',
$descriptors, $pipes);
$status = proc_get_status($process);
posix_kill($status['pid'], SIGTERM);
sleep(1);
$status = proc_get_status($process);
echo "Процесс работает: " . ($status['running'] ? 'Да' : 'Нет') . "\n";
echo "Код выхода: " . $status['exitcode'] . "\n";$process = proc_open('dd if=/dev/zero of=/dev/null count=100000',
$descriptors, $pipes);
$status = proc_get_status($process);
if ($status['running']) {
proc_nice($process, 10); // Устанавливаем низкий приоритет
echo "Приоритет изменен для PID: " . $status['pid'] . "\n";
}$process = proc_open('for i in {1..5}; do echo $i; sleep 0.5; done',
$descriptors, $pipes);
if (is_resource($process)) {
stream_set_blocking($pipes[1], false);
while (true) {
$status = proc_get_status($process);
// Чтение вывода
$output = fread($pipes[1], 1024);
if ($output !== false && $output !== '') {
echo "Вывод: $output";
}
if (!$status['running']) {
break;
}
usleep(100000);
}
fclose($pipes[1]);
proc_close($process);
}