Я написал простой, хотя и многопоточный генератор простых чисел.
Алгоритм выглядит так:
Поток 0: генерирует последовательные числа.
Потоки 1 .. N: отфильтровать числа, которые не являются простыми.
При каждом «новом» первичном обнаружении добавляется новый поток фильтра.
Взять I: нет управления потоком вообще.
Поток 0 'отправляет номера абсолютно бесплатно.
Программа завершается с сигналом 11 (ошибка сегмента), редко с сигналом 8, еще реже с успешным завершением.
Take II: управление потоком с параметром setMaxMailboxSize равным 1.
В большинстве случаев все работает хорошо.
Взять III:
Теперь, если все это было результатом какого-то внутреннего незаметного переполнения, оно должно хорошо работать с setMaxMailboxSize в 2 (или даже 10), я не прав?
Поток 0 застревает после первого блокирования.
Может кто-нибудь подсказать мне, что мне не хватает?
Примечание 1:
Я использую DMD v2.053 под Ubuntu 10.04
Примечание 2:
Это мой код:
#!/usr/bin/dmd -run
import std.stdio;
import std.conv;
import std.concurrency;
void main(string[] args)
{
/* parse command line arguments */
if (args.length < 2) {
writeln("Usage: prime <number of primes to generate>");
return;
}
auto nPrimes = to!int(args[1]);
auto tid = spawn(&generate, thisTid);
/* gather produced primes */
for (;;) {
auto prime = receiveOnly!int();
writeln(prime);
if (--nPrimes <= 0) {
break;
}
}
tid.send("stop");
}
void generate(Tid parentTid)
{
bool terminate = false;
// filter stage 1
auto tid = spawn(&filter_stage, parentTid);
/* WHAT DO I MISS HERE ? */
setMaxMailboxSize(tid, 1, OnCrowding.block);
for (int i = 2; !terminate; i++) {
receiveTimeout(0,
(string cmd) {
writeln(cmd);
terminate = true;
}
);
tid.send(i);
}
}
void filter_stage(Tid parentTid)
{
auto prime = receiveOnly!int();
parentTid.send(prime);
// filter stage 'N'
auto tid = spawn(&filter_stage, parentTid);
filter(prime, tid);
}
void filter(int prime, Tid tid)
{
for (;;) {
receive (
(int number) {
if (number % prime != 0) {
tid.send(number);
}
}
);
}
}