Xpoint
   [напомнить пароль]

DBI и fork

Метки: [без меток]
[удл]
2008-05-19 05:17:09 [обр] sawa[досье]
сообщение промодерировано
Суть проблемы в следующем. В родительском потоке создаю $dbh и $sth, затем делаю fork, и в дочернем процессе использую $dbh и $sth. $dbh один на оба процесса, а вот $sth по всей видимости дублируется. Как этого можно избежать? Если невнятно описал проблему то вот пример:
   my $dbh = $DB->connect(...);
   $dbh->{DBH}->{InactiveDestroy} = 1;
   my $sth = $dbh->prepare("
         insert into tmp_test (id, txt) values (:id, '')");

   $sth->{STH}->{InactiveDestroy} = 1;

        while(1)
        {
           if ($childs == 0)
           {
              my $pid;
              if (!defined($pid = fork))
              {
                 next;
              }
              elsif ($pid)
              {
                 $sys->log("session opened [pid $pid]"); 
                 $childs = 1;
                 $cnt++;
                 next;
              }
         $sth->bind_param(":id", $i);
         $sth->execute();
              exit();
           }
        }
спустя 1 час 21 минуту [обр] Роман Чемисов(36/350)[досье]
sawa[досье]
Правильный путь — подключаться к БД уже после fork'а.
спустя 1 час 54 минуты [обр] sawa[досье]
Роман Чемисов[досье]
Ну это понятно, просто хотелось, грубо говоря, один раз подготовить все sth's и использовать их в дочерних процессах
спустя 54 минуты [обр] Иванов Михаил aka Ivanych(0/70)[досье]
sawa[досье]
Вы не должны этого хотеть.
спустя 52 минуты [обр] sawa[досье]
Иванов Михаил aka Ivanych[досье] А почему???
В идеале конечно хотелось следующее: главный модуль ждет подключений по сокету, на каждое подключение создается дочерний процесс. Так вот хотелось иметь пул коннектов к базе, чтобы каждый раз в дочернем процессе не тратить на это время. С базой должен был работать только дочерний процесс. А в реальности с этим возникают проблемы...
спустя 1 час 56 минут [обр] Иванов Михаил aka Ivanych(0/70)[досье]

sawa[досье]

А почему???

Потому что дочерний процесс после выхода должен убрать за собой мусор. А убирая мусор, он закроет открытый дескриптор, т.е. закроет соединение с базой. Закрытие соединения дочерним процессом - это явно не то, что Вам нужно, поэтому Вы используете InactiveDestroy. Это, однако, обходной маневр, а прямое решение - соединяться с базой после форка.

спустя 15 часов [обр] sawa[досье]
Всем спасибо. Тему можно закрывать.
Powered by POEM™ Engine Copyright © 2002-2005