Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Паралелльные процессы в PHP

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Как можно создавать потомков процесса
SergeantPEPPER
Отправлено: 01 Апреля, 2008 - 09:54:44
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Здравствуйте,
скажите а как можно распараллелить один процесс в PHP и создать, ну скажем, пять потомков этого процесса?

Или даже не порождать несколько процессов, а содавать 5 потоков одного процесса...
Не знаю даже как это нормальнее будет выглядеть?

Если не сложно, подкиньте еще ссылку на хорошую литературу. Спасибо.

Попробовал разобраться сам:

CODE (text):
скопировать код в буфер обмена
  1. <?php
  2.  
  3. $child_num = 4;
  4.  
  5.  
  6. $fpid = pcntl_fork ();
  7. if ($fpid == -1) {
  8.         die ("could not fork!\n");
  9. } elseif ($fpid) {
  10.         // father process
  11.         exit ();
  12. } else {
  13.         // mother process
  14.         for ($i = 1; $i <= $child_num; $i++)
  15.         {
  16.                 $pid = pcntl_fork ();
  17.                 if ($pid == -1) die ("Could not fork!\n");
  18.                 elseif ($pid) $pid_array[$i] = $pid;
  19.                 else {
  20.                         echo "Im child process!\n";    
  21.                 }
  22.         }      
  23. }
  24. ?>


Однако такой код почему-то каждый раз выдает разное количество фраз
Im child process ???
Не пойму почему?

P.S. Я тестирую на Unix-системе

(Отредактировано автором: 01 Апреля, 2008 - 13:31:24)

 
 Top
SergeantPEPPER
Отправлено: 02 Апреля, 2008 - 09:04:49
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Товарищи, не бросайте меня )))

Тот код, что я приводил выше был взят с какого-то сайта и был неоправданно отягащен...

Как параллелить процесс я понял, однако вот проблема в другом: каждый порожденный процесс у меня работает с базой данных MySQL, и казалось бы первый отработавший процесс должен завершить соединение с ней, отрубив от MySQL оставшиеся, НО!!!
Не знаю почему из пяти параллельных дочерних процессов соединение может отрубиться после двух, трех или четырех процессов??? Не понял - Т.е. соединение с MySQL разрывается НЕ после первого процесса и "поработать" с ней успевает каждый новый раз разное количество процессов.

Я ничего не понимаю! Объясните, пожалуйста в чем дело!
 
 Top
SergeantPEPPER
Отправлено: 03 Апреля, 2008 - 08:16:08
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Ну, пообщаюсь немного сам с собой...

О причине такого странного поведения я догадался:

Так как соединение с MySQL рвется только ПОСЛЕ окончания работы с ним первого (самого быстрого) процесса, то можно предположить, что в промежутке между началом работы с MySQL и окончанием этого процесса , успевают воспользоваться текущим соединением и несколько других параллельных процессов. Ну и логично тогда, что каждый новый раз это число будет случайным... (ну или псевдослучайным)

Жаль, но проблема все же остается. Соединение с MySQL рвется и я с этим ничего поделать не могу, блин, я облазил кучу форумов и FAQ-ов, но ответа нигде нет...
А постояннам соединением через mysql_pconnect пользоваться не хочется (да в общем-то и не помогло)

Если кто-нибудь сталкивался с этим, НАПИШИТЕ please Однако
 
 Top
EuGen Администратор
Отправлено: 03 Апреля, 2008 - 10:34:44
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




А в чем задача, не ясно. Вам нужно, чтобы при наличии установленного соединения с БД в одном из процессов, другие процессы не могли соединиться с БД, или как?..


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
SergeantPEPPER
Отправлено: 04 Апреля, 2008 - 07:58:05
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Ну для начала, я хотел бы сделать такую программу:

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

При этом: соединение с MySQL открывается в начале главного процесса. Первый (самый быстрый) дочерний процесс после общения c MySQL это соединение завершает и MySQL становится недоступным для остальных. Так вот, моя задача в том, чтобы после отработки первого процесса соединение не завершалось (т.е. сохранялось), а закрывалось в конце гланого процесса.
 
 Top
EuGen Администратор
Отправлено: 04 Апреля, 2008 - 09:43:19
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




То есть Вы хотите, чтобы все потомки родительского процесса работали с одним соединением с БД?


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
SergeantPEPPER
Отправлено: 04 Апреля, 2008 - 12:20:38
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Да, именно так.
 
 Top
EuGen Администратор
Отправлено: 04 Апреля, 2008 - 13:21:39
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




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


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
expired
Отправлено: 04 Апреля, 2008 - 19:01:43
Post Id


Новичок


Покинул форум
Сообщений всего: 14
Дата рег-ции: Март 2008  


Помог: 0 раз(а)




хм, странно я видел люди пытались сделать что то подобное для кроны,
и для интернет чата,

а для чего вам это нужно?
 
 Top
SergeantPEPPER
Отправлено: 05 Апреля, 2008 - 15:48:02
Post Id



Частый гость


Покинул форум
Сообщений всего: 245
Дата рег-ции: Сент. 2007  
Откуда: Казань


Помог: 0 раз(а)




Извиняюсь за длительную задержку. Хм

Вот код (здесь все дочерние процессы работают через функцию child_main):

CODE (text):
скопировать код в буфер обмена
  1. // функция для дочернего потока
  2. function child_main ()
  3. {
  4.         $cpid = getmypid ();
  5.         //echo "Child process take off: $cpid\n";
  6.         DoQuery ("INSERT INTO `sends` (`login`, `email`, `message`) VALUES ('login-$cpid', 'email-$cpid', 'message-$cpid')")
  7.                 OR die ('MySQL error: ' . mysql_error () . "\n");
  8.         sleep (2);
  9. }
  10.  
  11. DoQuery("SET wait_timeout=28800");
  12.  
  13. for ($i = 1; $i <= 5; $i++)
  14. {
  15.         $pid = pcntl_fork ();
  16.         if ($pid == -1) die ("Error: pcntl_fork ()!\n");
  17.         elseif ($pid == 0) exit (child_main ());
  18.         else {
  19.                 $all_childs[i] = $pid;
  20.         }
  21. }
  22.  
  23. for ($i = 1; $i <= 5; $i++)
  24. {
  25.         $pid = $all_pids[i];
  26.         // берем статус дочернего процесса
  27.         // в $status передалась информация статуса процесса (при выходе)
  28.         $pid = pcntl_wait ($status);
  29.  
  30.         // есть ли статус успешного выхода
  31.         if (pcntl_wifexited ($status))
  32.         {
  33.                 $code = pcntl_wexitstatus ($status);
  34.                 echo "Process $pid return exit code: $code\n";
  35.         } else {
  36.                 echo "Process $pid was force destroyed\n";
  37.         }
  38. }


А понадобилось мне это, чтобы решить проблему, которая уже отпала... Улыбка
НО ради интереса и опыта хочу все-таки найти решение данного вопроса.

Мне нужно было забирать информацию сразу с нескольких веб-адресов, а так как задержки в Интернете в данном случае Очень существенны - последовательный способ работы приложения становится крайне невыгодным. Можете с этим поспорить...
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Программирование на PHP »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB