Есть некоторая задача, которая может быть решена с использованием процессов и SysV IPC или с использованием потоков. Выбор пал на второй вариант. До этого с потоками в перле никогда не работал. Скомпайлили на сервере (FreeBSD 4.9) перл 5.8.6 с поддержкой ithread, начал экспериментировать. Сначала был собран примитивный каркас, код которого приведен ниже.
#!/usr/bin/perl
use strict;
use threads;
use threads::shared;
#use CGI;
use constant MAX_THREAD => 50;
$| = 1;
my $thread_num : shared = 0;
my $exit = 0;
$SIG{INT} = sub { $exit++ };
while (!$exit) {
if ($thread_num < MAX_THREAD - 1) {
print "new thread (thread_num = $thread_num)\\n";
if (threads->create(\\&thread_do)) {
lock $thread_num;
$thread_num++;
} else {
die("Can\'t create thread: $@\\n");
}
}
}
print "Stopping...\\n";
#1 while $thread_num+;
print "Done\\n";
sub thread_do
{
threads->self->detach();
sleep(1 + int(rand(2)));
{
lock $thread_num;
$thread_num--;
}
}
Сей нехитрый скрипт работал так, как и было задумано. thread_num находился в приделах от 45 до 49, а при остановке выводилось ожидаемое сообщение "A thread exited while 50 threads were running". Проблемы начались после того, как я добавил одну строку – подключение модуля (что именно за модуль – значения не имеет, результат тот же) через use. Скрипт перестал корректно реагировать на INT сигнал, в 90% случаев делая после нескольких сигналов дамп памяти, а в остальных 10% - выводя сообщение с неверным числом потоков (от 50 до 70). При подключении тяжелых модулей, таких как DBI или LWP thread_num не поднималось выше 35 (при ограничении на количество потоков равным 50).
При выполнении некоторого кода в потоке (выполнял в блоке eval и проверял возврат), thread_num в течение нескольких минут показывало 10-15, затем резко возрастало до 49 (скорость была такая, как будто работало не 50, а 5 потоков), а при остановке писало, что работало 60-70 потоков.
Никакого логического объяснения ни одному из этих феноменов я дать не могу. Может кто-нибудь сталкивался с подобными проблемами и решал их?