Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Windows Script Host + COM + ThreadPool [D7, WinXP]


K1LLADR1LLA ©   (2008-10-27 17:53:00) 

Значит так.
Есть пул потоков QueueUserWorkItem, в callback методе
потока очереди
инициализится COM и создаётся COM-объект(Perl-скрипт мутящий текстовый файл по регулярному выражению).

К примеру, я создаю пул из 60 потоков и пихаю в каждый поток по одному заданию(текст+регулярное выражение), так вот странным образом, хотя и создаётся очередь из 60 потоков, обрабатывается корректно примерно 95% очереди, некотрорые потоки из пула странным образом не выполняются, и при этом никаких эксэпшынов не происходит в потоке.
Господа, что это может быть, в чем я туплю ?
=======CALLBACK функция для QueueUserWorkItem=========
function qGrepex(Value:Pointer):dword; stdcall;
//label LOOP;
var
 outs,rx,txt:string;
 ghost : OleVariant;
 val : TSIREXSValue;
 I: Integer;
begin
try
 Val    := TSIREXSValue(Value^);
 rx     := val.rx;
 txt    := val.txt;
           try
             CoInitializeEx
           (nil,COINIT_APARTMENTTHREADED);
            Ghost := CreateOleObject('psirexuwz.wsc'); //
           finally
 InterlockedIncrement(SIUtils.GPooled);
    Ghost.grepex(rx,txt);   // вызываю метод из скрипта.
 while outs='' do sleep(50);
 InterlockedDecrement(SIUtils.GPooled);
 InterlockedDecrement(siutils.GEventCounter);
 CoUninitialize;
end;
except
 on E:Exception do Tsrvc.PostLog('qGrepex :: '+E.Message);
end;
result := 0ж
end;
==================================================
====================Perl-скрипт=====================











 
 

                 
 
                 



#use strict;
   use threads;

use File::Basename;
my $wrk=0;

sub get_sum_len
{
  my ($x,@indata);
  my ($res,$i) = 0;
  my  @dout;
  ($x,@indata) = @_;
   for($i=0;$i


K1LLADR1LLA   (2008-10-28 14:34:00) [1]

мг, я буду иметь ввиду выше предложенное, хотя я уже мудохаюсь неделю ((=
Если смысла не видно, то это ещё не значит, что смысла нет ((=


Slym   (2008-10-28 14:19:00) [2]

смысла перевода непосредственного выполнения кода в теле потока в APC спящего потока я не вижу...


Slym   (2008-10-28 14:12:00) [3]

K1LLADR1LLA ©   (28.10.08 13:59) [8]
на вычисление регулярного выражения будут поступать огромные логи до 1ГБ

ИЧЁ? стопудофф линейно без пулофф (при текущей реализации) быстрее буит...

програм1

делаем потоки по колву процессоров

впотоке.еХекут
{
КоИнит;
обж:=КреатОбжект('psirexuwz.wsc');
дотехпорпокаживу дуит
{
задача:=ядро.дайзадачу
обж.коитус(задача)
ядро.яеёоткоитовал(задача)
}
КоДеИнит;
}


K1LLADR1LLA   (2008-10-28 13:59:00) [4]

CreateOleObject('psirexuwz.wsc') креатится постоянно... зачем? он stateless
----------------------------------------------------------------------------
если я создаю единожды CreateOleObject('psirexuwz.wsc') в другом потоке, и передаю OleVariant переменную в callback метод потока, то вылазит экцэпшн... но я перепроверю ещё раз.
----------------------------------------------------------------------------
не проще пересмотреть задачу и наити другое более линейное решение? без пула никак? в 1 потоке? или в CPUCount потоках?
----------------------------------------------------------------------------
Дело в том что, на вычисление регулярного выражения будут поступать огромные логи до 1ГБ, с множества (до 10000) клиентов, поэтому было решено юзать пул. Ну тоесть один раз при старте сервиса создаётся определённое кол-во потоков, в которые пихаются задачи.


Slym   (2008-10-28 13:38:00) [5]

Slym ©   (28.10.08 13:31) [6]
пулы не для этого придуманы...
придуманы они для распараллеливания часто простаивающих процедур для минимизации колва потоков и расходов с ними связанных: переключения потоков, стекпамять и т.п. и т.д.

Но у тебя узкое место далеко не этом... только хуже делаешь...
расходы при взаимодействии с COM подсистемой CoInitializeEx/CoUninitialize/CreateOleObject('psirexuwz.wsc') намного превысят "доходы" от QueueUserWorkItem


Slym   (2008-10-28 13:31:00) [6]

не проще пересмотреть задачу и наити другое более линейное решение? без пула никак? в 1 потоке? или в CPUCount потоках?
я к тому что всеравно активно будет не более CPUCount потоков...

CreateOleObject('psirexuwz.wsc') креатится постоянно... зачем? он stateless


K1LLADR1LLA   (2008-10-28 13:13:00) [7]

пардон , я нагнал, даже когда COINIT_MULTITHREADED , и работает один поток, всё-равно пропускает задания, казлина )=


Slym   (2008-10-28 11:54:00) [8]

ну все верно... когда по очереди все нормально проходят через узкую дверь... а когда "толпой" 5% в давке загибаются...
попробуй 1 раз COINIT_MULTITHREADED перед запуском пула, из калбека убери может само "синхронизируется" :)


K1LLADR1LLA   (2008-10-28 09:37:00) [9]

ааа,
while outs='' do sleep(50);
это я забыл закаментить, это сейчас не используется.
это я сделал для того, что бы поток из пула дождался результата из скрипта, потому как я думал, что поток завершается преждевременно.
-----------------------------------------------------------------------
Самое интересное, что с этим-то флагом COINIT_APARTMENTTHREADED, всё работает нормально, потоки добавляются в пул ,но как я уже сказал, всреднем, 5% потоков не выполняются корректно , хотя никаких исключений не вылазит. Если же ставлю флаг COINIT_MULTITHREADED, то пул так же создается, но активно выполняется один поток, все остальные ждут и в этом случае всё потоки выполняют работу корректно.
Скрипт регистрируется в реестре с ключём InprocServer32->ThreadingModel->Apartment


Slym   (2008-10-28 04:53:00) [10]

а разве так можно?
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
а CALLBACK функция для QueueUserWorkItem может менять поток (если не WT_EXECUTEINPERSISTENTTHREAD), т.е. с COM объектом созданным в одном потоке работа может происходить в нескольких других потоках тем более что ты принудительно усыпляешь sleep поток что может повлеч за собой переключение потока на другой колбек

http://vsokovikov.narod.ru/New_MSDN_API/Process_thread/thread_pool.htm

Обратите внимание! на то, что объединение потоков в пул не совместимо с моделью однопоточных апартаментов (STA).


Сергей М.   (2008-10-27 21:28:00) [11]


> в чем я туплю ?


Первая же "тупость", бросающаяся в глаза:


> while outs='' do sleep(50);


Что это за танцы с бубном ?
Кто и где изменяет содержимое переменной outs, так чтобы выполнилось условие выхода из цикла ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо