POE жалуется, что метод запуска POE :: Kernel никогда не вызывался, когда я форк - PullRequest
1 голос
/ 31 декабря 2010

Это мой код:

 if ($DAEMON) {
                my $pid = fork();
                if (not defined $pid) {
                                        print "Unable to start daemon.\n";
                                        exit(1);
                                      }
                elsif ($pid == 0) {
                                   open STDOUT, '>', '/dev/null';
                                   open STDERR, '>', '/dev/null';
                                   _create_sessions($self, $settings);
                                   $poe_kernel->run;
                                  }
                else { print "Script forked to background with PID $pid\n"; }
              }
 else {
        _create_sessions($self, $settings);
        $poe_kernel->run;
      }

Когда $ DAEMON = 1, он жалуется, что метод run () POE :: Kernel никогда не вызывался, но, как вы можете видеть в приведенном выше коде, я сделалэто уже.Скрипт прекрасно работает в режиме демона, но я не могу избавиться от этого предупреждения или понять, почему он так говорит.Я также попытался вызвать $ poe_kernel-> has_forked (), и это тоже ничего не изменило.

У меня нет идей.Любые предложения?

Обновлено, чтобы добавить : Может быть, я не достаточно ясно.Приведенный ниже код создает сеанс и запускает ядро.

_create_sessions($self, $settings);
$poe_kernel->run;

Работает отлично.Только когда тот же код выполняется внутри дочернего объекта fork, поэтому я могу отправить скрипт в фоновый режим, он говорит, что метод запуска POE :: Kernel не был вызван.Скрипт уходит в фоновый режим и работает как надо, что означает, что ядро ​​действительно работает.Я только хочу избавиться от этого надоедливого предупреждения.

Ответы [ 2 ]

2 голосов
/ 01 января 2011

ист прав. Предупреждение возникает из-за того, что экземпляры POE :: Session создаются в родительском процессе, но им не была предоставлена ​​возможность запуска.

% perl -wle 'use POE; POE::Session->create(inline_states=>{_start => sub {}})'
40023: Sessions were started, but POE::Kernel's run() method was never
40023: called to execute them.  This usually happens because an error
40023: occurred before POE::Kernel->run() could be called.  Please fix
40023: any errors above this notice, and be sure that POE::Kernel->run()
40023: is called.  See documentation for POE::Kernel's run() method for
40023: another way to disable this warning.

В приведенном выше примере 40023 - это идентификатор процесса, в котором обнаружена проблема.

Это похоже на предупреждение Perl о выходе из активных потоков:

% perl -wle 'use threads; threads->create(sub { sleep 3600 }); '
Perl exited with active threads:
  1 running and unjoined
  0 finished and unjoined
  0 running and detached

Хотя ваш фрагмент кода показывает, что сеансы создаются и запускаются в дочернем процессе, я подозреваю, что сеансы создаются до или после. Родительский процесс не завершается в вашем фрагменте, поэтому невозможно сказать, где будет выполняться выполнение?

Вы также должны вызвать POE :: Kernel-> has_forked () в дочернем процессе. Я не могу сказать, происходит ли это в вашем фрагменте кода.

Правильное решение - переместить все экземпляры сеанса в дочерний процесс при демонизации. Обходной обходной путь - вызвать POE :: Kernel-> run () сразу после использования POE :: Kernel и до того, как будут созданы какие-либо сеансы. run () вернется немедленно, потому что сеансов не существует, но вызов удовлетворяет условию, о котором вас предупреждают. Это способ сказать «да, да, но я знаю, что я делаю».

1 голос
/ 31 декабря 2010

Из документа POE :: Kernel run обычно вызывается как метод класса;что такое $ poe_kernel?

Где-то, кажется, вы начинаете сеанс, но не заканчиваете тем, что вызываете POE :: Kernel-> run ();

Обновление: после сообщения, которое вы видитевыводится с warn, а вы выбрасываете STDERR у ребенка, я предполагаю, что это родитель, который выдает предупреждение. Что-то , которое вы делаете (в коде, который вы не показываете, который загружает POE и устанавливает $ poe_kernel?), Фактически создает сеанс, по-видимому, непреднамеренно.короткий, но работоспособный пример, и вы либо сами найдете проблему, либо поможете другим найти ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...