![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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, так чтобы выполнилось условие выхода из цикла ?