powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [PHP] управление процессами
17 сообщений из 17, страница 1 из 1
[PHP] управление процессами
    #37619719
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
У меня стоит задача которую я могу решить двумя способами, но вот какой из них правильней, т.е с наименьшим потреблением ресурсов - я не знаю, по этому хочу услышать совет умных людей)).

Есть у меня PHP скрипт который запускается при подключении к сокету (порту) удаленным устройством. После подключения скрипт получает побайтовый поток ввода STDIN (данные от устройства).

Каждое подключение - это отдельный северный процесс (дочерний).

Я понимаю об управлении процессами, знаю что такое дочерний, зомби процесс,отправка сигнала процессу,PID и все остальное касательно процессов и php.

Задача - установить таймаут завершения процесса (скрипта), который принимает данные по STDIN. Но в том случае, если данных нет к примеру 3600 секунд. Т.е не один байт не передавался, но скрипт продолжает ожидать данные (байтовый поток).

Как я пытаюсь решить задачу.

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

Другой скрипт который работает по крону, каждые 3600 секунд проверяет файл логов PID и в случае если время между текущим и записанным по какому то процессу привышает 3600 сек, посылается сигнал процессу на корректное завершение.

Проблема в том - как хранить файлы логов и как осуществлять к ним доступ? Важно то, что нельзя использовать DB.
Т.е использовать один файл для всег логов, и с одной стороны к нему будет очередь за запись, с другой стороны на чтение.
Боюсь что буду задержки.

С другой стороны можно просто создавать файл PID_time.pid под каждый процесс и проверять наличие этих файлов кроном.

В любом случае - возможно что то посоветуете вы?*

Заранее благодарен!
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37621114
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Electric200,

не утверждаю, но что-то мне кажется ваша система чересчур сложной.

Electric200Есть у меня PHP скрипт который запускается при подключении к сокету (порту) удаленным устройством.Опишите подробнее, как это происходит.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37621791
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно действительно со стороны сложновато.
В общем в двух словах.
1. Некое устройство подключается к серверу по 10003 порту.
2. Некий демон на сервере мониторит внешние подключения.
3. При появлении подключения, передает дескриптор сокета (соединения) моему скрипту в потоке STDIN
4. Мой скрипт начинает побайтово получать данные. Получает именно побайтово до формирования условной посылки.
5. Скрипт ожидает получения всей условной пысылки, к примеру 12 байт. В случае если передалось только 8 байт, скрипт ожидает остальные байты.

По сути, задача установится макс. время для этого ожидания. Что бы скрипт не висел в процессе сервера и не дай бог ушел в зомби.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37622377
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Electric200, set_time_limit ?
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37622589
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
set_time_limit - будет останавливать скрипт в любом случае.
А мне нежно, в случае отсутствия потока данных.

Вот сейчас смотрю в сторону stream_ set_ timeout()
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37622768
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stream_ set_ timeout() не работает с SDTIN .. поиск продолжается..
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37624887
an0nym
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Electric200,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
[an0nym@localhost ~]$ cat input.php 
<?php
for ($i = 0;; ++$i)
{
  printf("%d\n", $i);
  sleep($i);
}
[an0nym@localhost ~]$ cat output.php 
<?php
stream_set_blocking(STDIN, 0);
$rss = array(STDIN);
$wss = $ess = null;
while (stream_select($rss, $wss, $ess, $argv[1]))
{
  printf("%f\n", microtime(true));
  echo stream_get_contents(STDIN);
}
printf("%f\n", microtime(true));
[an0nym@localhost ~]$ time php input.php | php output.php 5
1327087817.988219
0
1
1327087818.988345
2
1327087820.988437
3
1327087823.988534
4
1327087827.988655
5
1327087832.988771
6
1327087837.993888

real	0m21.023s
user	0m0.017s
sys	0m0.020s
[an0nym@localhost ~]$ 
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #37626741
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an0nym - спасибо за stream_select();
То что доктор приписал!)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
[PHP] управление процессами
    #39006025
antoshib
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задача у меня похожая, но возникла проблемка - необходимо запускать некий скрипт (питоновский), читать из него вывод и отправлять этот вывод подключающимся через websocket клиентам по мере появления данных. Всё это реализовал, работает нормально, но вывод отправляется только тогда, когда скрипт отрабатывает до конца, а не по мере появления данных. Что делаю не так?
Вот кусок кода:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
//  функция выполняется в дочернем процессе после fork-a
//
//
function server_loop($address, $port, $runCmdString){

	$socket = stream_socket_server("tcp://$address:$port", $errno, $errstr);
	
	if (!$socket) {	die("$errstr ($errno)\n");	}
	
	$proc = proc_open( $runCmdString
					,array(	array("pipe","r"),
							array("pipe","w"),
							array("pipe","w"))
					, $pipes);	

	if (!is_resource($proc)){ die("Could not start process\n");	}

	fclose($pipes[0]);
	
	stream_set_blocking( $pipes[1], 0 );
	stream_set_blocking( $socket,   0 );

	$connects = array();

	while (true) {
	
		//формируем массив прослушиваемых сокетов:
		$write= $connects; 
		$read = $connects;
		$read []= $socket;
		$read []= $pipes[ 1 ];
		
		$except = null;		

		if (!stream_select($read, $write, $except, null)) { // ожидаем доступные сокеты
			break;
		}

		if (in_array($socket, $read)) {//есть новое соединение
			//принимаем новое соединение и производим рукопожатие:

			if (($connect = stream_socket_accept($socket, -1)) 
			&&  ($info = handshake($connect))) {
				$connects[] =  $connect;//добавляем его в список необходимых для обработки
				onOpen($connect, $info);//вызываем пользовательский сценарий
			}
			
			unset($read[ array_search($socket, $read) ]);
		 }
		

		if (in_array($pipes[ 1 ], $read)) {	

 			$procOutput = fgets($pipes[1]);                     //есть данные на выходе канала скрипта
			$numSent	 = 0;
					
			foreach($connects as $connect) {			//обрабатываем все соединения
				dataSend($connect, "$procOutput");	//отправляем данные клиентам
				$numSent++;
			}
			
			echo "\n $numSent time(s) sent to clients [$procOutput]";
			
			unset( $read[ array_search($pipes[ 1 ], $read) ] );
			

			if ( feof($pipes[1]) )                                   // достигнут конец данных, выходим
				break;
			
		}
		

		foreach($read as $connect) {//обрабатываем все соединения
			$data = fread($connect, 100000);

			if (!$data) { //соединение было закрыто
				fclose($connect);
				unset($connects[ array_search($connect, $connects) ]);
				
				onClose($connect);//вызываем пользовательский сценарий
				continue;
			}

			onMessage($connect, $data);	//вызываем пользовательский сценарий
		}

	}
	
	fclose($socket);
	fclose($pipes[1]);
	
	proc_close( $proc );
}



function dataSend($connect, $strSend="") {

    $sw = encode( "Output|".gmdate("Y-m-d\TH:i:s\Z")."| $strSend");

    for ($written = 0;  $written < strlen($sw); $written += $fwrite) {

        $fwrite = fwrite($connect, substr($sw,  $written, 16));

        if ($fwrite === false) {
            return $written;
        }
    }
	
	return $written;
}
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39006718
antoshib
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Закомментировал proc_open и работу с его потоками, поставил вывод фиктивных данных:

Код: php
1.
2.
3.
4.
5.
	foreach($connects as $connect) {		//обрабатываем все соединения
			dataSend($connect, "Test");		//отправляем строку клиентам
			$numSent++;
		}	
		sleep(1); if (!$numloops--) break;



и стало всё работать, как и задумывалось. То есть proc_open или fgets мне блокирует весь вывод к клиентам. Как их пришаманить?
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39007117
antoshib
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разобрался, но без 0.5 литра не обошлось! %) Я пытался через proc_open запускать питоновские скрипты, а питон, по умолчанию, делает буферизацию перед выводом в консоль((( Сволочи. Случайно на это наткнулся, когда попробовал запустить башевский скрипт и он у меня отработал, как следовало. Теперь и питон заработал с опцией -u.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39007388
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
antoshib,
Ну так не только питон. PHP делает также. И для этого предусмотрены функции отключения/включения/очистки буфера. Я смотрел ваш пример, и по PHP примеру не увидел использование буфера. Ну а что там в питоне, не видно отсюда.
Вообще использовать нативную работу с сокетами в PHP не очень хорошая идея. Идея с форками еще напомнит вам о себе в будущем с не очень хорошей стороны. По этому советую посмотреть в сторону NodeJS для работы с сокетами, или если уж там нужно PHP, то Swoole . Но очень советую бросить затею с форками.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39007455
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Electric200an0nym - спасибо за stream_select();
То что доктор приписал!)

интересно, как ему селект помог, если у него проблема выставить таймаут, ну или уйти от блокировки при ожидании данных.

есчё более не понятно, пока эдин принимает данные на порту 10003, ведь никто другой на этот порт не подключиться! и упорное использование интеграция вместо итерация... мдя.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39008356
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453Electric200an0nym - спасибо за stream_select();
То что доктор приписал!)

интересно, как ему селект помог, если у него проблема выставить таймаут, ну или уйти от блокировки при ожидании данных.

есчё более не понятно, пока эдин принимает данные на порту 10003, ведь никто другой на этот порт не подключиться! и упорное использование интеграция вместо итерация... мдя.
Я не знаю о чем ты тут рассказываешь. Уходить от блокировки и не нужно. Устанавливаешь побайтовое чтение stream_get_contents в цикле с установленной проверкой stream_select() на сработку таймаута. Таймаут сработал - завершил скрипт. Сокеты мониторит на наличие входящих подключений inetd и передает поток PHP обработчику, который дальше работает с потоком. Все это происходит асинхронно. Хочешь могу даже пример кода показать если ты такая недоверчивая штучка)
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39009893
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Electric200alex564657498765453пропущено...


интересно, как ему селект помог, если у него проблема выставить таймаут, ну или уйти от блокировки при ожидании данных.

есчё более не понятно, пока эдин принимает данные на порту 10003, ведь никто другой на этот порт не подключиться! и упорное использование интеграция вместо итерация... мдя.
Я не знаю о чем ты тут рассказываешь. Уходить от блокировки и не нужно. Устанавливаешь побайтовое чтение stream_get_contents в цикле с установленной проверкой stream_select() на сработку таймаута. Таймаут сработал - завершил скрипт. Сокеты мониторит на наличие входящих подключений inetd и передает поток PHP обработчику, который дальше работает с потоком. Все это происходит асинхронно. Хочешь могу даже пример кода показать если ты такая недоверчивая штучка)

покажи. а то мож я действительно не понимаю чегото...
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39013409
Electric200
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
public function captureStream($numbyte, $delimeter = null)
    {
        $this->stream = null;
        //Проверяем есть ли данные на потоке
        for ($i = 1; $i <= $numbyte; $i++) {
            $write = null;
            $except = null;
            if (stream_select($this->stdin, $write, $except, $this->timeout) == 0) {
                $this->sendStream('TIMEOUT');
                stream_socket_shutdown($this->stdin[0], STREAM_SHUT_WR);
                die();
            } else {
                $byte = stream_get_contents($this->stdin[0], 1);
                if ($delimeter != null && $byte == $delimeter) {
                    break;
                }
                $this->stream .= $byte;
            }


        }
        $this->stream_buffer .= $this->stream;
        return $this->stream;
    }


Собственно пример выше.
...
Рейтинг: 0 / 0
[PHP] управление процессами
    #39208540
Teslenko Sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Electric200,

Вы можете мне помочь разобраться с именованным каналами, я ни разу, до этого, ими не пользовался а мне необходимо соединиться и наладить обмен с вот этим https://yadi.sk/d/37nrmRktqccAV
Он отвечает на соединение socket_connect() от клиента, но после попытки отправить сообщение с помощью socket_write() разрывает соединение, при эта утилитка в лог пишет, что слишком длинное сообщение.
Я не учился на программиста, поэтому слабо понимаю суть процесса, немного плаваю.

Основная проблема в том что я не понимаю как необходимо указывать строку для создания pipe ресурса, и в какой момент времени.
Если вам не сложно вы не могли бы помочь?
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [PHP] управление процессами
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]