Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Аналог EasyDBI


Автор: shamber 18.4.2008, 15:33
Доброго времени суток. 
Вот возник вопрос - задача.

Похожая тема проскакивала http://forum.vingrad.ru/topic-186456.html но ответа небыло никакого smile

Пишу прогу c использованием wxPerl. Скрипт под Windows.
Прога активно работает с БД. И когда происходит считывание данных или загрузка в БД часто интерфейс "подвисает".
Появилась мысль, может если запустить отдельный тред или процесс, который будет обрабатывать запросы от/к бд, то может избавлюсь от тормозов?
Внимание вопрос, как организовать взаимодействие с этим отдельным процессом?
Я смутно догадываюсь, что стоит использовать threads или fork, но на чем лучше остановиться?
И самое главное возможно ли добиться функционала EasyDBI: после отработки запроса вызывать 
определенный метод из определенного package?




Автор: KSURi 18.4.2008, 17:07
Сложно сказать не видя самого скрипта и его структуры.
Однако, попробую предложить вариант запуска запросов через threads c последующим вызовом "определенных методов из определенного package".

Писал прямо в форум, так что на работоспособность даже не претендует.
Код

#...

my $dbh = DBHandler->connect;

#...

sub SendDbQueryViaThreads {
 my $query = shift;
 my $res = threads->create(\&DBHandler::do, $dbh, $query)->join;
 if($res eq 'bla1') { CustomHandler->method1 }
 elsif($res eq 'bla2') { CustomHandler->method2 }
 #...
}

Автор: shamber 18.4.2008, 17:43
KSURi, правильно поправил я выразился совершенно не ясно.
Объясняю более обстоятельно.

когда человек делает запрос к EasyDBI,
что-то типа этого
Код


    $kernel->post( 'EasyDBI',
        quote => {
#отправляем sql запрос
                sql => 'foo$*@%%sdkf"""',
#результат хотим в эту "сессию"
         session => 'ret',
#вот этот метод
          method =>test,
               
        }
    );


когда EasyDBI отработает она передаст результат в сессию ret и вызовет метод test.

кроме того есть стойкое желание иметь доступ к этому DBI thread из любого пакета входящего в состав программы.

Я не могу понять как можно создать процесс\поток в который можно будет передавать данные куда нужно вернуть данные, 

что-то типа ссылки на пакет и метод, но ведь blessed структуры нельзя расшарить для thread?

кроме того ведь если делать ->join, то не будет "паралельности", нужно будет все равно ждать пока thread отработает или я не прав?
а ждать не хочется, так как в этом случае "подвисает" интерфейс.


Автор: tolkien 19.4.2008, 00:44
Межпроцессорное взаимодействие сделайте с помощью сокетов. Работать будет везде.

Если ваш скрипт будет работать под Windows. то не используйте fork. Он очень плохо под виндус работает. Лучше использовать winapi. Ну, а в Unix fork. 

###Unix
my $pid = fork;
die  "DEBUG fork can't create child process" unless (defined($pid));

if ($pid == 0)
{
    exec ("perl -w script.pl") or die "can't exec script.pl"; 
}

###Windows
use Win32::Process;
$appname = 'F:/perl/bin/perl.exe';

Win32::Process::Create($ProcessObj, $appname,
  "perl -w script.pl.pl",
      0,
      NORMAL_PRIORITY_CLASS,
      ".")|| die ErrorReport();

sub ErrorReport{
        print Win32::FormatMessage( Win32::GetLastError() );
}

Автор: Ramirez 21.4.2008, 10:15
В POE это делается через Wheel::Run.  EasyDBI  тоже кажется так работает.
Можно запустить любой процесс или свой скрипт (который например под POE не хочется переписывать) отдельным подпроцессом в системе, при этом ядро POE сохранит с ним связь через стандартный воод/вывод....

Автор: JUmPER 22.4.2008, 16:50
не советую использовать перловые потоки: они не очень дружат с XS модулями
// кстати, на виндах форк тоже через потоки работает...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)