Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];

Вниз

Windows Script Host + COM + ThreadPool   Найти похожие ветки 

 
K1LLADR1LLA ©   (2008-10-27 17:53) [0]

Значит так.
Есть пул потоков 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-скрипт=====================

<?xml version="1.0"?>
<component>

<?component error="true" debug="true"?>

<registration
description="psirexuwz"
progid="psirexuwz.WSC"
version="2.00"
classid="{dabdb3f5-197a-403f-bc59-68094655e5f7}"
>
</registration>

<public>
<method name="grepex" dispid = "1">
 <PARAMETER name="RegexPattern"/>
 <PARAMETER name="Filename"/>
</method>
                  <method name="stoop" dispid="2">
 
                  </method>
</public>

<script language="PerlScript">
<![CDATA[
#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<$x;$i++)
   {
     $res = ($res + length($indata[$i]));
     $dout[$i] = $i<=0?$res:$res-length($indata[$i]);
   }  
   return @dout;
}
sub grepex{
  open(in0,$_[0]);
  open(in00,$_[1]);
  open(in000,">".dirname($_[0])."\\xfile");
  exit if -e dirname($_[0])."\\rslt";
  my $d1r = ">".dirname($_[0])."\\rslt";
  open(out0,$d1r);
  my (@data,@dout,@expr,@res);
  my ($dlen,$exp,$cnt,$j) ;
  my ($i,$cpos,$gcpos,$llen,$flag);  
  @data = <in00> ;
  @expr = <in0>  ;
  $dlen = scalar(@data);
  @dout = get_sum_len($dlen,@data);  
  eval
  {
  foreach $exp(@expr)
  {
     if($wrk == 0)
  {
   $cnt+=1;
   for($i=0;$i<$dlen;$i++)
   {  
     while($data[$i]=~m/$exp/gxc)    
     {    
         $cpos  = (pos($data[$i]) - length($&))  ;
         $gcpos = ($dout[$i] + $cpos);        
         $res[$j++] = $cnt."p".      
         ($gcpos+($i)."l".length($&))."m".$&."\n";
     }
    }    
   }
  }
 }

   $res[0]=$@ if $@;
   $res[0]=($res[0] eq ""? "$nrslt$":$res[0]);
   
     print out0 @res;
     close(out0);
   close(in0);
   close(in00);
   return join("",@res);  
   @res="";    
}

====================Perl-скрипт=====================
]]>
</script>

</component>


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


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


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


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


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


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

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

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

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


 
K1LLADR1LLA ©   (2008-10-28 09:37) [3]

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


 
Slym ©   (2008-10-28 11:54) [4]

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


 
K1LLADR1LLA ©   (2008-10-28 13:13) [5]

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


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

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

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


 
Slym ©   (2008-10-28 13:38) [7]

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

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


 
K1LLADR1LLA ©   (2008-10-28 13:59) [8]

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


 
Slym ©   (2008-10-28 14:12) [9]

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

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

програм1

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

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


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

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


 
K1LLADR1LLA ©   (2008-10-28 14:34) [11]

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



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.007 c
2-1256728258
kirat
2009-10-28 14:10
2009.12.13
cp866


2-1256283306
grav
2009-10-23 11:35
2009.12.13
Выгрузка сообщений об ошибках в текстовый файл


2-1256283325
Sergey2
2009-10-23 11:35
2009.12.13
insert ряд значений


2-1256122585
FEV
2009-10-21 14:56
2009.12.13
Число в строке...


2-1256201388
ghost
2009-10-22 12:49
2009.12.13
проверка на недопустимые символы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский