Oc-windows.ru

IT Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Php id процесса

getmyp >(PHP 4, PHP 5, PHP 7)

getmypid — Получение ID процесса PHP

Описание

Получает идентификатор PHP процесса.

Возвращаемые значения

Возвращает идентификатор PHP процесса или FALSE в случае ошибки.

Примечания

Идентификаторы процессов в системе не уникальны, это может привести к неоднозначности определения процесса. Мы не рекомендуем полагаться на pid в контекстах, влияющих на безопасность.

Смотрите также

  • getmygid() — Получение GID владельца PHP скрипта
  • getmyuid() — Получение UID владельца скрипта PHP
  • get_current_user() — Получение имени владельца текущего PHP скрипта
  • getmyinode() — Получение значения inode текущего скрипта
  • getlastmod() — Определение времени последней модификации страницы

Коментарии

One good use for this is deciding on a concurrency-safe temporary file or directory name. You can be assured that no two processes on the same server have the same PID, so this is enough to avoid collisions. For example:

= «/tmp/foo_» . getmypid ();
// Use $tmpfile.
// Use $tmpfile.
// Use $tmpfile.
unlink ( $tmpfile );
?>

If you are sharing /tmp over the network (which is odd. ) then you can, of course, mix in the PHP server’s IP address.

You can use this function also to avoid more than one instance of your app.

You can also use this class.
http://www.pure-php.de/node/20

if( ProcessHandler :: isActive ()) <
die( «Already running!n» ;);
>else <
ProcessHandler :: activate ();
//run my app
>

mixed getpidinfo(mixed pid [, string system_ps_command_options])

this function gets PID-info from system ps command and return it in useful assoc-array,
or return false and trigger warning if PID doesn’t exists

Array
(
[USER] => user
[PID] => 12345
[%CPU] => 0.0
[%MEM] => 0.0
[VSZ] => 1720
[RSS] => 8
[TT] => ??
[STAT] => Is
[STARTED] => 6:00PM
[TIME] => 0:00.01
[COMMAND] => php someproces.php > logfile
)

function getpidinfo ( $pid , $ps_opt = «aux» )<

$ps = shell_exec ( «ps » . $ps_opt . «p » . $pid );
$ps = explode ( «n» , $ps );

if( count ( $ps ) 2 ) <
trigger_error ( «PID » . $pid . » doesn’t exists» , E_USER_WARNING );
return false ;
>

foreach( $ps as $key => $val ) <
$ps [ $key ]= explode ( » » , ereg_replace ( » +» , » » , trim ( $ps [ $key ])));
>

foreach( $ps [ 0 ] as $key => $val ) <
$pidinfo [ $val ] = $ps [ 1 ][ $key ];
unset( $ps [ 1 ][ $key ]);
>

if( is_array ( $ps [ 1 ])) <
$pidinfo [ $val ].= » » . implode ( » » , $ps [ 1 ]);
>
return $pidinfo ;
>

Looking to create a lock-file mechanism for a cmd-line script?

#!/usr/bin/php
( ‘LOCK_FILE’ , «/var/run/» . basename ( $argv [ 0 ], «.php» ). «.lock» );
if( isLocked () ) die( «Already running.n» );

# The rest of your script goes here.
echo «Hello world!n» ;
sleep ( 30 );

unlink ( LOCK_FILE );
exit( 0 );

function isLocked ()
<
# If lock file exists, check if stale. If exists and is not stale, return TRUE
# Else, create lock file and return FALSE.

if( file_exists ( LOCK_FILE ) )
<
# check if it’s stale
$lockingPID = trim ( file_get_contents ( LOCK_FILE ) );

# Get all active PIDs.
$pids = explode ( «n» , trim ( ` ps -e | awk ‘‘ ` ) );

# If PID is still active, return true
if( in_array ( $lockingPID , $pids ) ) return true ;

# Lock-file is stale, so kill it. Then move on to re-creating it.
echo «Removing stale lock file.n» ;
unlink ( LOCK_FILE );
>

file_put_contents ( LOCK_FILE , getmypid () . «n» );
return false ;

We also had this challenge in our company to prevent a php script in a cron job from overlapping each other.

We made this solution

// Initialize variables
$found = 0 ;
$file = basename ( __FILE__ );
$commands = array();

// Get running processes.
exec ( «ps w» , $commands );

// If processes are found
if ( count ( $commands ) > 0 ) <

foreach ( $commands as $command ) <
if ( strpos ( $command , $file ) === false ) <
// Do nothin’
>
else <
// Let’s count how many times the file is found.
$found ++;
>
>
>

// If the instance of the file is found more than once.
if ( $found > 1 ) <
echo «Another process is running.n» ;
die();
>

The ‘ps’ command has an option that can make filtering for a specific process more efficient. Using this the work of looking for matching processes can be made neater:

/*
Return an array of the pids of the processes that are running for the specific command
e.g.
returnPids(‘myprocess.php’);
*/
function returnPids ( $command ) <
exec ( «ps -C $command -o p > , $pids );
foreach ( $pids as $key => $value ) $pids [ $key ]= trim ( $value );
return $pids ;
>

/*
Returns an array of the pids for processes that are like me, i.e. my program running
*/
function returnMyPids () <
return returnPids ( basename ( $_SERVER [ «SCRIPT_NAME» ]));
>
?>

e.g. to bomb out if I’m running already

if (count(returnMyPids())>1) exit;

Based on what james at voodoo dot co dot uk said, but modified for CLI scripts (ie: there is no $_SERVER).

/**
* Check for a current process by filename
* @param $file[optional] Filename
* @return Boolean
*/
function processExists ( $file = false ) <

$exists = false ;
$file = $file ? $file : __FILE__ ;

// Check if file is in process list
exec ( «ps -C $file -o p > , $pids );
if ( count ( $pids ) > 1 ) <
$exists = true ;
>
return $exists ;
>

All of the examples above require you to have shell command execution turned on- this example uses only PHP functions and should work on any system (posix is included by default)-

the key is posix_getsid which will return FALSE if the processes does not exist.

= sys_get_temp_dir () . ‘/myScript.lock’ ;
$pid = file_get_contents ( $lockfile );
if ( posix_getsid ( $pid ) === false ) <
print «process has died! restarting. n» ;
file_put_contents ( $lockfile , getmypid ()); // create lockfile
> else <
print «PID is still alive! can not run twice!n» ;
exit;
>
?>

🙂 perfect if you need to make sure a cron job or shell script has ended before it can be started again.

This works across users- if the cron job is started as ‘root’ your ‘web user’ can see if the process is still alive (useful for system status pages)

Here is how you’d use exec on a posix system to accomplish counting processes quickly.

I want to know how many processes are running with ‘update.php’ in the command:

ps aux|grep «[u]pdate.php»|wc -l

(the trick of using [u]pdate.php instead of update.php makes sure that the grep command itself is not matched). Be sure to use quotes in the command, or it won’t work either.

function countProcesses ( $scriptName )
<
// ps aux|grep «[u]pdate.php»|wc -l
$first = substr ( $scriptName , 0 , 1 );
$rest = substr ( $scriptName , 1 );

$name = ‘»[‘ . $first . ‘]’ . $rest . ‘»‘ ;
$cmd = «ps aux | grep $name | wc -l» ;

$result = exec ( $cmd );

On Linux you can check if a process is still running by verifying if the PID exists in the /proc directory :

if( file_exists ( ‘/proc/’ . $pid ))
<
echo ‘The process is still running.’ ;
>
?>

The lock-file mechanism in Kevin Trass’s note is incorrect because it is subject to race conditions.

For locks you need an atomic way of verifying if a lock file exists and creating it if it doesn’t exist. Between file_exists and file_put_contents, another process could be faster than us to write the lock.

The only filesystem operation that matches the above requirements that I know of is symlink().

Thus, if you need a lock-file mechanism, here’s the code. This won’t work on a system without /proc (so there go Windows, BSD, OS X, and possibly others), but it can be adapted to work around that deficiency (say, by linking to your pid file like in my script, then operating through the symlink like in Kevin’s solution).

#!/usr/bin/php
( ‘LOCK_FILE’ , «/var/run/» . basename ( $argv [ 0 ], «.php» ) . «.lock» );

if (! tryLock ())
die( «Already running.n» );

# remove the lock on exit (Control+C doesn’t count as ‘exit’?)
register_shutdown_function ( ‘unlink’ , LOCK_FILE );

Читать еще:  Php dir exists

# The rest of your script goes here.
echo «Hello world!n» ;
sleep ( 30 );

function tryLock ()
<
# If lock file exists, check if stale. If exists and is not stale, return TRUE
# Else, create lock file and return FALSE.

if (@ symlink ( «/proc/» . getmypid (), LOCK_FILE ) !== FALSE ) # the @ in front of ‘symlink’ is to suppress the NOTICE you get if the LOCK_FILE exists
return true ;

# link already exists
# check if it’s stale
if ( is_link ( LOCK_FILE ) && ! is_dir ( LOCK_FILE ))
<
unlink ( LOCK_FILE );
# try to lock again
return tryLock ();
>

My lockfile system

function isLocked () <
if( file_exists ( LOCK_FILE )) <
$lockingPID = trim ( file_get_contents ( LOCK_FILE ));
$test = trim (` ps -p $lockingP > `);
if(!empty( $test )) return true ;
echo «Removing stale lock file.n» ;
unlink ( LOCK_FILE );
>
file_put_contents ( LOCK_FILE , getmypid (). «n» );
return false ;
>
?>

hharek

В программирование бывает необходимость писать программы, которые должны работать непрерывно, причины тому могут быть: непрерывное отслеживание изменений на сайте, длительное выполнение какой-либо операции, веб-сокет сервер и другие. И для небольших программ язык PHP, как никогда подходит лучше всего. Здесь я попытаюсь описать возможные шаги, которые нужно предпринять чтобы написать свою программу работающую в среде Linux. Я предполагаю что Вы уже знакомы с Линукс и слова «консоль» и «ssh» Вас уже не пугают. Примеры команд будут запущены в среде Debian Linux 8.4, с PHP 7. Сам PHP 7 установлен как CLI.

Оглавление

Процесс в Linux

Запуская программу в Unix вы создаёте «процесс», т.е. процессор начинает выполнять инструкции программы. Чтобы не запутаться в названиях «программа» и «процесс» можно представить, что «программа» это некоторая бумага с текстом приказа, а «процесс» это робот который читает приказ и выполняет его. Вполне может быть что процесс может удалить программу, которая его запустила или что процесс запустил другие программы, т.е. вызвал другие процессы.

Запуская программу в Unix процессу присваиваются некоторые параметры, а именно:

PID — уникальный номер процесса. С помощью PID можно отправить сигнал процессу, узнать о его состоянии. PID всегда уникален и предсказать этот номер не представляется возможным. Если выполнить в консоле команду то увидим ID процесса.

* Запуская программу в консоли я использую на конце символ «&», это я делаю для того чтобы после запуска в консоли можно было запускать другие программы, т.е. не быть заблокированным своим процессом.

Имя — имя процесса формируется из имени программы и параметры его запуска. Т.е. если выполнить в консоли « php sleep.php & » процесс будет называться « php sleep.php » если же выполнить « /usr/local/bin/php sleep.php & », то процесс будет называться « /usr/local/bin/php sleep.php ». Но так бывает не всегда, при желании процесс может задать себе новое какое пожелает. Пример:

Вывод команды ps будет напоминать что-то вроде этого.

Я всё же рекомендую не использовать в имени процесса UTF-8 символы и спец символы, во избежания проблем с операционными системами Unix, без поддержки Unicode на уровне ядра.

PP >init » или « systemd », он является родоначальников всех процессов и его запускает само ядро Linux. У процесса всегда есть родитель, если родительский процесс закрывается все потомки родительского процесса «усыновляются» процессом « init » или « systemd ». Если вы запускаете программу через консоль, то родителем процесса будет консольная программа, вероятно « tcsh », « bash » или « zsh ». Посмотреть иерархию процессов можно так:

UID — UID пользователя, который запустил процесс. После запуска процессу ещё присваивается владелец и группа (почти как у файла) и с правами этого пользователя процесс будет работать. К примеру если мы запустим программу от пользователя «user1» находящегося в группе «group1», то процесс сможет выполнять действия доступные пользователю «user1», и не сможет скажем зайти в папку «/root» или удалить файл, владелец которого является пользователь «user2».

Аргументы программы — строки указанные в консоле при запуске программы после имени программы через пробел. Например если в консоли запустить программу: «php example.php a b -p1 —test=2», аргументами будут строки «a», «b», «-p1», «—test=2». В PHP аргументы программы можно найти в глобальном массиве $argv, а кол-во аргументов можно найти в глобальной переменной «$argc». Пример:

Закрытие процесса

В большинстве случаев процесс сам знает когда ему закончить работу, т.е. выполнил программу и завершился, но бывают случаи, когда процесс необходимо завершить принудительно. Для того чтобы обратиться к процесс нужно знать его P >kill ». Пример:

Бывает такое что процесс не может завершиться, то тогда ему нужно отправить сигнал «принудительное закрытие», это делается командой « kill -9 PID ». Ещё процесс можно завершить по имени процесса, для этого используйте команду « killall ».

Если вы запустили программу и программа заблокировала консоль используйте сочетание клавиш « Ctrl + C » и программа завершится. Или если просто хотите вернуться консоль не закрывая программу, то нажмите « Ctrl + Z », а далее « bg ».

Программы Linux для работы с процессами

Программ для работы с процессами множество, я же расскажу о программах которые мне нравятся больше и популярные примеры их использования. Речь пойдёт о программах: ps , pgrep , kill , htop .

ps — показывает запущенные процессы и сведения по ним. Примеры:

* — Если написать просто «ps -ef | grep «simple.php»», то отобразиться не только нужный нам процесс и сведения о самом нашем процессе «ps» и это может запутать.

pgrep — ищет процесс по имени и возвращает PID процесса. В отличии от ps не возвращает PID самого себя, а только нужный нам. В большинстве случаев результат программы pgrep используется другими программами. Примеры:

kill — отправить сигнал процессу. Не стоит пугаться названия этой программы, она не только завершает процесс, но и может отправить разные сигналы процессу. В основном используется чтобы принудительно закрыть процесс.

* Если процесс не настроен на «ловлю» этого сигнала процесс завершиться.

htop — программа для мониторинга процессов в реальном времени. Программа позволяет узнать загруженность системы, а также узнать какие процессы используют большую часть процессорного времени или оперативной памяти. Удобно запускать в отдельном окне и заглядывать туда.

pstree — показать дерево процессов. Можно посмотреть всю иерархию процессов или всех «предков» процесса.

Непрерывный процесс

Теперь нам нужно добиться того чтобы наш скрипт работал постоянно (а не выключался после запуска), для этого нам достаточно написать бесконечный цикл, к примеру вот так:

Если мы запустим этот скрипт, у нас действительно процесс будет запущен постоянно, но при этом мы получим почти 100% загрузку процессора, т.е. итерации цикла будут выполняться постоянно со 100% скоростью. Чтобы этого избежать нагрузку процессора, но при этом получать отклик необходимо по окончании каждой итерации цикла останавливать скрипт на некоторое количество времени. Для этого можно использовать функции « sleep » или « usleep », при « sleep » указывается время в секундах, а при «usleep» время в микросекундах, т.е. « sleep(2) = usleep(2000000) ». Переделаем наш скрипт:

Здесь «usleep» будет означать, время отклика ваше программы на внешние раздражители (сигналы, сокеты и прочее).Теперь вместо почти 100% загруженности получим почти 0% загруженность процессора при простаивании процесса. Вероятно программа, которая работает в фоне будет не просто выполняться в бесконечном цикле, а ждать поступления определённого события (сигналы, таймер, поступление данных на канал или сокет, изменения в файлах и прочее), здесь же скрипт предоставлен в качестве примера.

Отвязываемся от консоли

Мы научились запускать процессы в режиме ожидания, теперь необходимо чтобы процесс смог самостоятельно работать и не быть «привязанным к консоли». Запуская свои программы в консоли мы можем заметить пока программа выполняется, другие программы запускать в консоли не получается. Есть несколько способов запустить программу в фоновом режиме.

Читать еще:  Fetch assoc php

Используйте символ « & » (Амперса́нд) после набора команды. Пример:

Консоли бывают разные (bash, tcsh, zsh и др.) и некоторые консоли (но не tcsh) при закрытии отправляют процессам специальный сигнал «SIGHUP», после чего программы завершают своё выполнение. Чтобы этого избежать используйте программу «nohup», она гарантирует что после закрытия консоли программы не закроются.

После запуска программы нажмите сочетание клавиш « Ctrl + Z » и далее команду « bg ». Сочетаниями клавиш мы ставим процесс на «паузу» и командой « bg » «будим» процесс и он продолжает работать работать в фоне.

Ещё один способ подразумевает что запущенный процесс (родительский процесс) «склонирует» себе подобный процесс (дочерний процесс) т.е. «форкнется» и завершиться. Родительский процесс завершиться, а дочерний процесс продолжит работу, к тому же он усыновляется процессом « init » и перестаёт быть зависимым от консоли. Я считаю этот способ более предпочтительным, т.к. нам теперь нет необходимости на конце писать символ « & » и следить не закроется ли он после закрытия консоли.

Одна программа — один процесс

Запуская нашу программу несколько раз мы будем постоянно «плодить» одинаковые процессы, нам же нужно чтобы программа порождала только один процесс. Чтобы программа запускалась только один раз, нужно чтобы она перед запуском опрашивала систему на поиск себе подобных процессов. Один из способов узнать запущенна ли уже программа это использовать «p >posix_getpid . Создаётся pid-файл вот так:

Далее при каждом запуске программы, программа будет читать этот файл и на указанный P >posix_kill », которая отправит сигнал процессу. В функции указать сигнал с номером « 0 ».

Теперь напишем программу, которая будет запускаться только один раз:

Программа запустилась только один раз.

PHP-программа как Unix скрипт

Чтобы запускать php-программу, как обычный Unix-скрипт (т.е. вместо « php script.php » писать « ./script.php »), необходимо в начале файла (перед « ») программы написать путь к интерпритатору, который будет обрабатывать этот файл (в нашем случае это php ). Путь к интерпритатору будет начинаться с символов « #! ». Также нужно задать файлу права на выполнение к примеру 755 , что будет означать — разрешено запускать скрипт всем.

Теперь если запустить файл без указания интерпритатора, то программа запуститься через «/usr/bin/php», если запустить с указанием интерпритатора, то программа запустить через указнный в консоли интерпритатор. Пример:

Если же ваш скрипт будет использоваться в системах, где php может находиться в разных местах используйте такой путь к интерпритатору « #!/usr/bin/env php »

Многопроцессовые демоны на PHP

Рано или поздно приходится на сайте выполнять задачи, которые прямо на страничке делать ну никак не получается. Обрабатывать большие объемы данных. Запрашивать медленные внешние сервисы. Делать сложные расчеты.

Тут-то и приходится вспоминать, что PHP – не только препроцессор домашних страниц, а и полноценный скриптовый язык. Давайте на этом языке сделаем демона для выполнения фоновых задач.

Основы

  • PID – идентификатор процесса. Уникальное для текущего момента положительное число.
  • pcntl – расширение PHP для работы с дочерними процессами. Курим мануал.
  • posix – расширение PHP для работы с функциями стандарта POSIX. Курим мануал.

Если у тебя возникнет вопрос по поводу какой-то незнакомой функции — не расстраивайся! Они все задокументированы в PHP Manual. Вряд ли у меня получится рассказать о них подробнее и интереснее.

Форкинг (плодим процессы)

Как из одного процесса сделать два? Программистам под Windows (в том числе и мне) больше знакома система, когда мы пишем функцию, которая будет main() для дочернего потока. В Linux все не так, потому я немного расскажу об этой системе многопроцессовости. Линуксоиды могут смело пропустить эту часть, если они и так все знают.

Итак. Есть такая функия pcntl_fork . Она делает две вещи: копирует всю память, выделенную под текущий процесс и запускает еще один процесс из того же места, откуда была вызвана, но с использованием новой копии данных.

Таким образом, после pcntl_fork мы остаемся с двумя одинаковыми запущенными скриптами.

Если просто вставить в скрипт pcntl_fork , ничего наглядного ты не увидишь, разве что конфликты доступа к ресурсам. Поэтому pcntl_fork возвращает 0 дочернему процессу и PID дочернего процесса – родительскому. Вот обычный способ использования pcntl_fork :

Кстати, pcntl_fork работает только в CGI и CLI-режимах. Из-под апача — нельзя. Логично.

Демонизация

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

После таких действий мы остаемся с демоном — программой без консоли. Чтобы она не завершила свое выполнение немедленно, пускаем ее в бесконечный цикл (ну, почти):

Дочерние процессы

На данный момент наш демон однопроцессовый, и будет обрабатывать по одной задаче одновременно. Чтобы запускать более одной задачи, нужно отфоркать еще несколько процессов. Это даст нам возможность задействовать более одного ядра процессора (если они есть), или более эффективно опрашивать блокирующие внешние ресурсы — базы данных, сервисы, сайты, и т.п.

Рассмотрим создание дочерних процессов.

Обработка сигналов

Следующая по важности задача – обеспечение обработки сигналов. Сейчас наш демон ничего не знает о внешнем мире, и убить его можно только завершением процесса через kill -SIGKILL . Это плохо. Это очень плохо – SIGKILL прервет процессы на середине. Кроме того, ему никак нельзя передать информацию.

Есть куча интересных сигналов, которые можно обрабатывать, но мы остановимся на SIGTERM — сигнале корретного завершения работы.

Вот и все. Мы перехватываем сигнал, ставим флаг в скрипт, и используем этот флаг, чтоб не запускать новые потоки и завершить основной цикл.

Поддержание уникальности демона

И последний штрих. Нужно, чтобы демон не запускался два раза. Обычно для этих целей используется т.н. .pid-файл: файл, в котором записан pid данного конкретного демона, если он запущен.

После демонизации нужно записать в pid-файл текущий PID демона.

Вот и все, что нужно знать для написания демонов на PHP. Я не рассказывал об общем доступе к ресурсам, потому что эта проблема шире, чем написание демонов.

hharek

В программирование бывает необходимость писать программы, которые должны работать непрерывно, причины тому могут быть: непрерывное отслеживание изменений на сайте, длительное выполнение какой-либо операции, веб-сокет сервер и другие. И для небольших программ язык PHP, как никогда подходит лучше всего. Здесь я попытаюсь описать возможные шаги, которые нужно предпринять чтобы написать свою программу работающую в среде Linux. Я предполагаю что Вы уже знакомы с Линукс и слова «консоль» и «ssh» Вас уже не пугают. Примеры команд будут запущены в среде Debian Linux 8.4, с PHP 7. Сам PHP 7 установлен как CLI.

Оглавление

Процесс в Linux

Запуская программу в Unix вы создаёте «процесс», т.е. процессор начинает выполнять инструкции программы. Чтобы не запутаться в названиях «программа» и «процесс» можно представить, что «программа» это некоторая бумага с текстом приказа, а «процесс» это робот который читает приказ и выполняет его. Вполне может быть что процесс может удалить программу, которая его запустила или что процесс запустил другие программы, т.е. вызвал другие процессы.

Запуская программу в Unix процессу присваиваются некоторые параметры, а именно:

PID — уникальный номер процесса. С помощью PID можно отправить сигнал процессу, узнать о его состоянии. PID всегда уникален и предсказать этот номер не представляется возможным. Если выполнить в консоле команду то увидим ID процесса.

* Запуская программу в консоли я использую на конце символ «&», это я делаю для того чтобы после запуска в консоли можно было запускать другие программы, т.е. не быть заблокированным своим процессом.

Имя — имя процесса формируется из имени программы и параметры его запуска. Т.е. если выполнить в консоли « php sleep.php & » процесс будет называться « php sleep.php » если же выполнить « /usr/local/bin/php sleep.php & », то процесс будет называться « /usr/local/bin/php sleep.php ». Но так бывает не всегда, при желании процесс может задать себе новое какое пожелает. Пример:

Читать еще:  Снять защиту doc

Вывод команды ps будет напоминать что-то вроде этого.

Я всё же рекомендую не использовать в имени процесса UTF-8 символы и спец символы, во избежания проблем с операционными системами Unix, без поддержки Unicode на уровне ядра.

PP >init » или « systemd », он является родоначальников всех процессов и его запускает само ядро Linux. У процесса всегда есть родитель, если родительский процесс закрывается все потомки родительского процесса «усыновляются» процессом « init » или « systemd ». Если вы запускаете программу через консоль, то родителем процесса будет консольная программа, вероятно « tcsh », « bash » или « zsh ». Посмотреть иерархию процессов можно так:

UID — UID пользователя, который запустил процесс. После запуска процессу ещё присваивается владелец и группа (почти как у файла) и с правами этого пользователя процесс будет работать. К примеру если мы запустим программу от пользователя «user1» находящегося в группе «group1», то процесс сможет выполнять действия доступные пользователю «user1», и не сможет скажем зайти в папку «/root» или удалить файл, владелец которого является пользователь «user2».

Аргументы программы — строки указанные в консоле при запуске программы после имени программы через пробел. Например если в консоли запустить программу: «php example.php a b -p1 —test=2», аргументами будут строки «a», «b», «-p1», «—test=2». В PHP аргументы программы можно найти в глобальном массиве $argv, а кол-во аргументов можно найти в глобальной переменной «$argc». Пример:

Закрытие процесса

В большинстве случаев процесс сам знает когда ему закончить работу, т.е. выполнил программу и завершился, но бывают случаи, когда процесс необходимо завершить принудительно. Для того чтобы обратиться к процесс нужно знать его P >kill ». Пример:

Бывает такое что процесс не может завершиться, то тогда ему нужно отправить сигнал «принудительное закрытие», это делается командой « kill -9 PID ». Ещё процесс можно завершить по имени процесса, для этого используйте команду « killall ».

Если вы запустили программу и программа заблокировала консоль используйте сочетание клавиш « Ctrl + C » и программа завершится. Или если просто хотите вернуться консоль не закрывая программу, то нажмите « Ctrl + Z », а далее « bg ».

Программы Linux для работы с процессами

Программ для работы с процессами множество, я же расскажу о программах которые мне нравятся больше и популярные примеры их использования. Речь пойдёт о программах: ps , pgrep , kill , htop .

ps — показывает запущенные процессы и сведения по ним. Примеры:

* — Если написать просто «ps -ef | grep «simple.php»», то отобразиться не только нужный нам процесс и сведения о самом нашем процессе «ps» и это может запутать.

pgrep — ищет процесс по имени и возвращает PID процесса. В отличии от ps не возвращает PID самого себя, а только нужный нам. В большинстве случаев результат программы pgrep используется другими программами. Примеры:

kill — отправить сигнал процессу. Не стоит пугаться названия этой программы, она не только завершает процесс, но и может отправить разные сигналы процессу. В основном используется чтобы принудительно закрыть процесс.

* Если процесс не настроен на «ловлю» этого сигнала процесс завершиться.

htop — программа для мониторинга процессов в реальном времени. Программа позволяет узнать загруженность системы, а также узнать какие процессы используют большую часть процессорного времени или оперативной памяти. Удобно запускать в отдельном окне и заглядывать туда.

pstree — показать дерево процессов. Можно посмотреть всю иерархию процессов или всех «предков» процесса.

Непрерывный процесс

Теперь нам нужно добиться того чтобы наш скрипт работал постоянно (а не выключался после запуска), для этого нам достаточно написать бесконечный цикл, к примеру вот так:

Если мы запустим этот скрипт, у нас действительно процесс будет запущен постоянно, но при этом мы получим почти 100% загрузку процессора, т.е. итерации цикла будут выполняться постоянно со 100% скоростью. Чтобы этого избежать нагрузку процессора, но при этом получать отклик необходимо по окончании каждой итерации цикла останавливать скрипт на некоторое количество времени. Для этого можно использовать функции « sleep » или « usleep », при « sleep » указывается время в секундах, а при «usleep» время в микросекундах, т.е. « sleep(2) = usleep(2000000) ». Переделаем наш скрипт:

Здесь «usleep» будет означать, время отклика ваше программы на внешние раздражители (сигналы, сокеты и прочее).Теперь вместо почти 100% загруженности получим почти 0% загруженность процессора при простаивании процесса. Вероятно программа, которая работает в фоне будет не просто выполняться в бесконечном цикле, а ждать поступления определённого события (сигналы, таймер, поступление данных на канал или сокет, изменения в файлах и прочее), здесь же скрипт предоставлен в качестве примера.

Отвязываемся от консоли

Мы научились запускать процессы в режиме ожидания, теперь необходимо чтобы процесс смог самостоятельно работать и не быть «привязанным к консоли». Запуская свои программы в консоли мы можем заметить пока программа выполняется, другие программы запускать в консоли не получается. Есть несколько способов запустить программу в фоновом режиме.

Используйте символ « & » (Амперса́нд) после набора команды. Пример:

Консоли бывают разные (bash, tcsh, zsh и др.) и некоторые консоли (но не tcsh) при закрытии отправляют процессам специальный сигнал «SIGHUP», после чего программы завершают своё выполнение. Чтобы этого избежать используйте программу «nohup», она гарантирует что после закрытия консоли программы не закроются.

После запуска программы нажмите сочетание клавиш « Ctrl + Z » и далее команду « bg ». Сочетаниями клавиш мы ставим процесс на «паузу» и командой « bg » «будим» процесс и он продолжает работать работать в фоне.

Ещё один способ подразумевает что запущенный процесс (родительский процесс) «склонирует» себе подобный процесс (дочерний процесс) т.е. «форкнется» и завершиться. Родительский процесс завершиться, а дочерний процесс продолжит работу, к тому же он усыновляется процессом « init » и перестаёт быть зависимым от консоли. Я считаю этот способ более предпочтительным, т.к. нам теперь нет необходимости на конце писать символ « & » и следить не закроется ли он после закрытия консоли.

Одна программа — один процесс

Запуская нашу программу несколько раз мы будем постоянно «плодить» одинаковые процессы, нам же нужно чтобы программа порождала только один процесс. Чтобы программа запускалась только один раз, нужно чтобы она перед запуском опрашивала систему на поиск себе подобных процессов. Один из способов узнать запущенна ли уже программа это использовать «p >posix_getpid . Создаётся pid-файл вот так:

Далее при каждом запуске программы, программа будет читать этот файл и на указанный P >posix_kill », которая отправит сигнал процессу. В функции указать сигнал с номером « 0 ».

Теперь напишем программу, которая будет запускаться только один раз:

Программа запустилась только один раз.

PHP-программа как Unix скрипт

Чтобы запускать php-программу, как обычный Unix-скрипт (т.е. вместо « php script.php » писать « ./script.php »), необходимо в начале файла (перед « ») программы написать путь к интерпритатору, который будет обрабатывать этот файл (в нашем случае это php ). Путь к интерпритатору будет начинаться с символов « #! ». Также нужно задать файлу права на выполнение к примеру 755 , что будет означать — разрешено запускать скрипт всем.

Теперь если запустить файл без указания интерпритатора, то программа запуститься через «/usr/bin/php», если запустить с указанием интерпритатора, то программа запустить через указнный в консоли интерпритатор. Пример:

Если же ваш скрипт будет использоваться в системах, где php может находиться в разных местах используйте такой путь к интерпритатору « #!/usr/bin/env php »

Ссылка на основную публикацию
Adblock
detector