The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"fork и fetchrow_array()"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"fork и fetchrow_array()" 
Сообщение от maxim emailИскать по авторуВ закладки(??) on 04-Окт-05, 19:26  (MSK)
Господа, помогите в таком вопросе.

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

примерный код:
#!/usr/bin/perl
use DBI;

$ENV{"ORACLE_HOME"}="/usr/local/oracle/orahome";
$ENV{"NLS_LANG"}="american_AMERICA.cl8mswin1251";
$ENV{"ORACLE_SID"}="etc434";
$ENV{"ORACLE_OWNER"}="oracle";
$ENV{"ORACLE_BASE"}="/opt/oracle/etc434db";

die "Couldn't connect to database: " . DBI->errstr if(!($dbh = DBI->connect('DBI:Oracle:etc434','www','password')));
$sql = "select DOMAIN_NAME from nwww.contact_information_domains where STATUS = 0 ";
die "Couldn't prepare statement: " . $dbh->errstr if(!($sth = $dbh->prepare($sql)));
$sth->execute();

for ($i = 1; $i <=5 ; $i++){
        if (!defined($pid = fork())) {
                die "cannot fork: $!" ;
        } elsif(!$pid) {
               while (@data = $sth->fetchrow_array()) {
# здесь код обработки @data ;
                }
        } else {
                $lastpid = $pid ;
                undef $pid ;
        }
}
waitpid($lastpid, 0) ;
sth->finish();
dbh->disconnect();

проблема в том что все 5 процессов делают fetchrow_array() паралельно. т.е. все 5-ть обрабатывают одну и туже строку ( и потом вместе переходят к следующей). вместо вечного двигателя получился вечный тормоз :(

как это можно исправить ?

возможно это не правильно решение моей задачи, подскажи пожалуста более правильное.
  

  Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "fork и fetchrow_array()" 
Сообщение от Andrey Искать по авторуВ закладки(??) on 05-Окт-05, 16:09  (MSK)
Разделить выборку по какому-либо параметру, и дать каждому процессу обрабатывать свой кусок.

>die "Couldn't connect to database: " . DBI->errstr if(!($dbh = DBI->connect('DBI:Oracle:etc434','www','password')));

Пиши проще: connect(...) || die ... .

И присоединяться к базе лучше после fork'а.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "fork и fetchrow_array()" 
Сообщение от maxim emailИскать по авторуВ закладки(??) on 05-Окт-05, 17:20  (MSK)
а почему лучше после forka, в чем разница ?
  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "fork и fetchrow_array()" 
Сообщение от Andrey emailИскать по авторуВ закладки(??) on 05-Окт-05, 21:28  (MSK)
>а почему лучше после forka, в чем разница ?

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

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "fork и fetchrow_array()" 
Сообщение от mthawk emailИскать по авторуВ закладки(??) on 06-Окт-05, 10:49  (MSK)
>проблема в том что все 5 процессов делают fetchrow_array() паралельно. т.е. все
>5-ть обрабатывают одну и туже строку ( и потом вместе переходят
>к следующей). вместо вечного двигателя получился вечный тормоз :(
>
>как это можно исправить ?
>
>возможно это не правильно решение моей задачи, подскажи пожалуста более правильное.
>


Если я все правильно понял, то возможно есть смысл предоставить возможность каждому из скриптов обрабатывать N строк из запроса.
$scripts=5; #Предположим 5 форков.
$rows=$sth->rows; #Получаешь общее количество строк из запроса;
$fetchres=$sth->fetchall_array;
Каждый потомок должен знать свой номер.
Пусть он получает его из цикла форка.
for($mynum=1; $mynum<=$scripts;$mynum++)
{
тут форчишься.
если детенок = выходишь из цикла
если родитель - след. итеррация
}
Выйдя из цикла смотришь - если детенок
имеешь свой номер
диапазон строк рассчитывашь по схеме
$start=int($rows/$scripts)*($mynum-1); #Первая строка запроса, которую обрабатывает скрипт
$rowlen=int($rows/$scripts); #кол-во строк которое обрабатывает скрипт
ну а дальше
for($i=$start;$i<$start+$rowlen;$i++)
{
делаешь что то c $fetchres->[$i][....];
}

ПОМНИ!!!! Функция int возвращает целую часть.
Может (и будет) так что последняя строка запроса не обработается.
Делай поправку на ветер.
sub myint
{
my $p=shift;
$ip=int($p);
$ip++ if ($p>$ip);
return $ip;
}
или последнему потомку вместо for($i=$start;$i<$start+$rowlen;$i++)
в качестве цикла дай for($i=$start;$i<$rows;$i++)

Надеюсь был полезен.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "fork и fetchrow_array()" 
Сообщение от maxim emailИскать по авторуВ закладки(??) on 07-Окт-05, 14:09  (MSK)
>Если я все правильно понял, то возможно есть смысл предоставить возможность каждому
>из скриптов обрабатывать N строк из запроса.

Ага, так и сделал. Все получилось очень не плохо.
Спасибо большое.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ]
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру