|
Тема
|
perl & threads
|
|
Автор |
ZeroFill (непознат
) |
Публикувано | 11.01.05 17:03 |
|
Здравейте!
Имам да пиша perl скрипт, който прави разни мрежови заявки в multithread режим като броя на running тредовете трябва да бъде ограничен до n примерно. За да стане това трябва да преброя тия тредове, които работят, а не тия, които вече са си свършили работата и са exit-нали. Според документацията:
Listing current threads
You can get a list of current thread objects in the current process using the Thread->list class method call. The list includes both running threads and threads that are done but haven't been joined yet.
Ако направя горепосочения join на даден тред, той не се включва в Thread->list без значение дали работи или е приключил т.е. не ми върши работа.
Та въпросът ми е дали някой се е занимавал с такова чудовище и как мога да взема броя на running тредовете в даден момент.
Благодаря.
| |
|
Това е горе долу метода. Но thread-овете в Perl са експериментални, и практически почти нищо не им работи. Ако N е по-малко от 10, може да работиш и с процеси (fork) като мастер процеса прихваща SIGCHLD и от там брои намаляването на пуснатите под деца. Това обаче също не е сигурен механизъм защото ако две деца умрат едновременно няма да получиш двоен сигнал, а само веднъж и след известен период от време се натрупват грешки. Аз силно ти препоръчвам да използваш SELECT/POLL или Non Blocking IO. Като SELECT също има известни проблеми при някой UNIX реализации (може да каже че има нещо на дескриптора а всъщност да няма, и програмата да се блокира). Като цяло моят опит (а той е наистина голям) показва че най-стабилно работи Non Blocking IO. Като изключим Threads модела, всичко друго не е проблем на Perl-а а на операционната система. За съжаление обаче се среща много често
| |
|
"с процеси (fork) като мастер процеса прихваща SIGCHLD и от там брои намаляването на пуснатите под деца. Това обаче също не е сигурен механизъм защото ако две деца умрат едновременно няма да получиш двоен сигнал, а само веднъж и след известен период от време се натрупват грешки."
Ако изпълнява редовно wait мастер процеса ще изтрепва всички деца подали SIGCHLD , като го вади от стека. Но много интересно това което пишеш - тогава детето на което не е прихванат SIGCHLD-а би трябвало да остава зомби за системата и да не се хване от wait-а. Не съм сигурен как точно ще се държи wait-а на мастера в този случай - дали ще трепе наред всички свои зомбита или само на някои ...
| |
|
Точно така става - зомбира се :) Това е много дискусионен въпрос. Често съм стигал проследявайки процеса до бъгове в кернелите на операционните системи. Във FreeBSD и Linux (освен 2.6, там за сега не съм забелязал) съм хващал доста проблеми. Програми, които интензивно раждат и убиват деца натрупват проблеми много бързо. Slowaris се държи мааалко по добре от тази гледна точка. Но тук стои следният важен проблем:
Ако ти трябва нещо сигурно и не искаш да се възползваш от това да имаш 2 или повече процесора (или MultiCore процесорите, идат вече...) по добре заложи на единственото сигурно, където контрола винаги е в теб - Non blocking IO :) без много Select - там също има бъгове.
| |
Тема
|
Re: perl & threads
[re: ZeroFill]
|
|
Автор | HP-UX admin (Нерегистриран) |
Публикувано | 06.02.05 08:49 |
|
Pravish edin cycle sus broia na threads koito iskash da ti rabotiat nesto takova:
my %Threads = ();
for (0..$MAXThreads){
$Threads->[$_] = threads->new(\&Function, $par1, $par2);
print "Thread " . ($_ + 1) . " created.\n";
}
"Function" e "zacyclena" kato proveriava dali opredelena shared variable e sus STOP value ( ste triabva da mozesh da spresh tazi programa ako iskash) t.e. ako e STOP spira.
Ostava da napulnish cycla na Function sus coda deto ste ti vurshi rabota.
| |
Тема
|
Re: perl & threads
[re: ZeroFill]
|
|
Автор | acд (Нерегистриран) |
Публикувано | 13.04.05 17:13 |
|
Ще дадете ли малко повече инфо за Non blocking IO?
| |
Тема
|
Re: perl & threads
[re: acд]
|
|
Автор |
zuluz ($>=$<=0) |
Публикувано | 14.04.05 13:46 |
|
Пример за 'non-blocking server':
Ако мислиш, че това е недостатъчно - използвай 'Super Search'
#~
$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[9,0,15,7])})/]
#~
| |
|
|
|
|