Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.10.2012, 16:54   #1
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию демон на php, убить дочерний процес после того как он сделал то нчо от него требуется

доброго времени суток. Пишу небольшой демон на php.
Возникла проблема в том что не могу понять как завершать дочерние процесы.

Код демона нарыл на хабаре

То что сейчас у меня:

PHP код:
<?php
pcntl_signal_dispatch
();
//declare(ticks=1); 

class DaemonClass {
     
// Максимальное количество дочерних процессов
    
public $maxProcesses 5;
    
// Когда установится в TRUE, демон завершит работу
    
protected $stop_server FALSE;
    
// Здесь будем хранить запущенные дочерние процессы
    
protected $currentJobs = array();
    protected 
$socket;
    protected 
$conf = array();
    
    public function 
__construct() {
        echo 
"Сonstructed daemon controller".PHP_EOL;
        
// Ждем сигналы SIGTERM и SIGCHLD
        
pcntl_signal(SIGTERM, array($this"childSignalHandler"));
        
pcntl_signal(SIGCHLD, array($this"childSignalHandler"));
    }
    public function 
Create(){
        
$this->conf Config::Ini('config.ini''config');
        
// Создание сокета TCP:
        // возвращает дескриптор сокета
        
if(($this->socket socket_create(AF_INETSOCK_STREAMSOL_TCP)) < 0
        { 
            
error_log('Невозможно создать сокет: '.socket_strerror(socket_last_error())."\n");
        }else{
            
// Биндим сокет на определённый адрес и порт:
            
if(($error socket_bind($this->socket$this->conf->host$this->conf->port)) < 0
            { 
                
error_log('Невозможно привязать сокет: '.socket_strerror(socket_last_error())."\n");
            }else{
                
//Прослушиваем сокет:
                
if(($error socket_listen($this->socket5)) < 0
                { 
                    
error_log('Невозможно прослушать сокет: '.socket_strerror(socket_last_error())."\n");
                }else{
                    
$this->run();
                }
            }
        }
    }
    protected function 
run(){
        echo 
"Running daemon controller".PHP_EOL;
        
        
// Пока $stop_server не установится в TRUE, гоняем бесконечный цикл
        
while (!$this->stop_server) {
            
// Если уже запущено максимальное количество дочерних процессов, ждем их завершения
            
while(count($this->currentJobs) >= $this->maxProcesses) {
                 echo 
"Maximum children allowed, waiting...".PHP_EOL;
                 
sleep(1);
            }
           
$this->launchJob();
        }
        
// Закрываем сокет 
        
socket_close($this->socket);
    }
    protected function 
launchJob() { 
        
// Создаем дочерний процесс
        // весь код после pcntl_fork() будет выполняться
        // двумя процессами: родительским и дочерним
        
$pid pcntl_fork();
        if(
$pid == -1) {
            
// Не удалось создать дочерний процесс
            
error_log('Could not launch new job, exiting');
            return 
FALSE;
        }elseif(
$pid){
            
// Этот код выполнится родительским процессом
            
$this->currentJobs[$pid] = TRUE;
        }else{
            
// А этот код выполнится дочерним процессом
            
echo "Процесс с ID ".getmypid().PHP_EOL;
            
// ожидаем соединение
            
if(($accept socket_accept($this->socket)) < 0
            {
                
error_log('Ошибка при чтении');
                
// закрываем соединение 
                
socket_close($accept);
                unset(
$this->currentJobs[$pid]);
                exit(); 
            }else{
                print(
date("Y-m-d H:i:s"time())." STATUS: client connected.\n");
                
// Считываем заданное количество байт из указанного сокета 
                    
if(FALSE === ($line = @socket_read($accept2048))) 
                    { 
                        
error_log('Невозможно прослушать сокет: '.socket_strerror(socket_last_error())."\n");
                        
socket_close($accept);
                        unset(
$this->currentJobs[$pid]);
                        exit(); 
                    }else{
                        
$query trim($line);
                        
file_put_contents(DOCUMENT_ROOT."/query.log"$query."\n"FILE_APPEND);
                        unset(
$this->currentJobs[$pid]);
                        exit(); 
                    }
            }
        }
        return 
TRUE
    }
    public function 
childSignalHandler($signo$pid null$status null) {
        switch(
$signo) {
            case 
SIGTERM:
                
// При получении сигнала завершения работы устанавливаем флаг
                
$this->stop_server true;
                break;
            case 
SIGCHLD:
                
// При получении сигнала от дочернего процесса
                
if (!$pid) {
                    
$pid pcntl_waitpid(-1$statusWNOHANG); 
                } 
                
// Пока есть завершенные дочерние процессы
                
while ($pid 0) {
                    if (
$pid && isset($this->currentJobs[$pid])) {
                        
// Удаляем дочерние процессы из списка
                        
unset($this->currentJobs[$pid]);
                    } 
                    
$pid pcntl_waitpid(-1$statusWNOHANG);
                } 
                break;
            default:
                
// все остальные сигналы
        
}
    }
}
проблема возникает в самом launchJob.

Как видите тут:
PHP код:
unset($this->currentJobs[$pid]);
exit(); 
я пытался убрать запись о процессе
dem66 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
После того, как поменяли кулер комьютер не включается explosion14 Компьютерное железо 1 23.10.2012 20:54
убить процес TIVA_PW Microsoft Office Excel 3 27.07.2011 00:57
Canvas не перерисовывается после того, как зайдёт за границу экрана TwiX Мультимедиа в Delphi 10 05.03.2010 10:21
Как присвоить значение max всем элементам стоящим после него? Defa4ka Помощь студентам 9 13.11.2009 18:37
ошибка, после того как я создал запись 'fayl' ZhekON Общие вопросы Delphi 15 01.04.2007 13:39