опять разветвление процессов, "переключение"

Bagroff

Новичок
опять разветвление процессов, "переключение"

Пытаюсь разобраться с идеологией разветвления процессов, подправьте где не прав...

Код, ессес-но не рабочий, просто идея...

PHP:
// Создаем сокет, привязываемся на какой-то сетевой интерфейс и порт
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
socket_bind ($socket, $host, $port);
socket_listen ($socket, 5);

...

// Ждем соединений...
while (true) { 
	$msg_socket = socket_accept($socket);
	$pid = pcntl_fork();
	if ($pid == -1) {
		die('Could not fork child process');
	} else if ($pid) {
		// родитель
	} else {
		// порожденный процесс
		// выполняем прикладную логику, какую-то...
		SocketInit();     // читаем что пришло, socket_read
		SocketAction(); // чего-то делаем...		
		SocketWrite();  // чего-то пишем в ответ
		SocketClose();  // закрываемся...
		// теперь нужно убиться, но это как-то через лес...
		posix_kill(posix_getpid(), 9);       		
	}
}
Мне навеяло :), примерно так... подправьте plz.

Ситуация вторая.

Хотелось бы поступать след. образом в идеале.

Висит сервер на locahost:2222 ждет соединений. Приперся клиент на localhost:2222, приперся с одназначно идентифицирующим себя(клиента) каким-то ключем, если ключа нет(новый клиент) делаем для него pcntl_fork "выполняемся" в этом процессе и оставляем child-процесс жить дальше в ожидании возвращения клиента с таким же ключем. Если же клиент, приперся с ключем, для которого уже был создан child-процесс когда-то, как "переключить" клиента на нужный child-процесс чтобы "выполниться" там с уже существующим каким-то окружением?

Пните идей, каша в голове :)
 

hermit_refined

Отшельник
posix_kill(posix_getpid(), 9);
просто exit(0); не хотите?
(+ вам нужно не забывать о зомби.)
Если же клиент, приперся с ключем, для которого уже был создан child-процесс когда-то, как "переключить" клиента на нужный child-процесс чтобы "выполниться" там с уже существующим каким-то окружением?
на php нет возможности передать дескриптор от одного процесса другому.
и вообще идея хранить один процесс для каждого пользователя - не из лучших.
а если пользователей мало - вполне можно их в одном процессе обслуживать.

если вы делаете что-то серьёзное - http://www.books.ru/shop/books/460327 и пишите на C.
если для развлечения - упростите задачу до минимума. и посмотрите всякие простые реализации серверов (опять-таки на C, потому как на комментарии пользователей в мануале по этой теме лучше не ориентироваться.)
 

voodoo

Новичок
ну убиться можно по exit, а так, в общем, должно работать. апач же работает :)

Если же клиент, приперся с ключем, для которого уже был создан child-процесс когда-то, как "переключить" клиента на нужный child-процесс чтобы "выполниться" там с уже существующим каким-то окружением?
тут сложно, при форке процесс получает все данные родителя, но что происходит потом (новый сокет) чайлду неизвестно.
Т.е. все это, в принципе, можно сделать, напр.: родитель должен проанализировать запрос, потом передать клиентский сокет нужному чайлду (т.е. еще и общение по юникс-сокету должно быть, причем что делать если чайлд занят чем-то другим?) В общем, задача в таком виде не для пхп (хотя можно модуль дописать для передачи сокета).
 

Bagroff

Новичок
Спасиб! Уложилось в голове...

Я тоже задумался о том, чтобы в каждом child`e поднимать socket unix... и дальше задумался о том, а что если он - этот child-процесс все ещё занят...

Вопрос с продолжение о pcntl'e ? Аналог для виндов? Попробовал сейчас cygwin, но аналога не нашел... как поступить тогда в виндах, т.е. распаралелить процесс...?
 

Bagroff

Новичок
Автор оригинала: hermit_refined
и что вы с ним, простите, делать будете?..передавать через него запросы-ответы?..
Да ничего, полет фантазии это, никак не приближенный к земле, т.е. реальности...

хм, вам unix'а мало?
да, к сожалению, иногда будет винда.
 

Bagroff

Новичок
я в курсе, от сюда и вопрос:
Аналог для виндов?
-~{}~ 02.03.07 14:22:

Автор оригинала: hermit_refined
просто exit(0); не хотите?
(+ вам нужно не забывать о зомби.)
замучился с темой зомби, скорей всего от собственного непонимания...


PHP:
        pcntl_signal(SIGHUP,   array(&$this, "SigHandler"));
        pcntl_signal(SIGTERM, array(&$this, "SigHandler"));
// Вроде бы, должны свалиться(self::SigHandler) когда у child`а exit(); ? 
        pcntl_signal(SIGCHLD, array(&$this, "SigHandler"));

{...}

        function SigHandler ($signo) {
        	file_put_contents('/var/www/aaa.aaa', "SigHandler(".$sig[$signo].")\n");
         	
        	switch($signo) { 
            	case SIGCHLD:            		
            		while (($pid=pcntl_wait($status, WNOHANG)) > 0 ) {
      					$this->child = array_diff( $this->child, array($pid));
					    if (!pcntl_wifexited($status)) {
         					file_put_contents('/var/www/aaa.aaa', "Аннулирован уничтоженный процесс ".$pid."\n");
      					}
      					else {
         					file_put_contents('/var/www/aaa.aaa', "Аннулирован завершенный процесс ".$pid."\n");
      					}
   					}   					
            	break;
    	        default: 
            		// file_put_contents('/var/www/aaa.aaa', "catch signal ".$signo."\n"); 
            	break; 
        	}
но не приходим мы в sighandler вообще... :(
 
Сверху