#d
#d
Вопрос:
Я написал простой, хотя и многопоточный генератор простых чисел. Алгоритм выглядит следующим образом: поток 0: генерирует последовательные числа. Потоки 1 .. N: отфильтровывают числа, которые не являются простыми. При каждом «новом» первичном обнаружении добавляется новый поток фильтра.
Возьмите I: никакого управления потоком вообще. Поток 0 ‘отправляет номера абсолютно свободно. Программа завершается сигналом 11 (ошибка сегмента), редко сигналом 8, еще реже завершается успешно.
Возьмите 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(amp;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(amp;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(amp;filter_stage, parentTid);
filter(prime, tid);
}
void filter(int prime, Tid tid)
{
for (;;) {
receive (
(int number) {
if (number % prime != 0) {
tid.send(number);
}
}
);
}
}
Комментарии:
1. возможно, вы создаете для многих потоков
2. ~ 1000 потоков — это слишком много? Сделай мне одолжение !
Ответ №1:
Звучит как ошибка в std.concurrency. Попробуйте обновить DMD до 2.055. Я не уверен, исправлена ли эта конкретная ошибка, но между 2.053 и 2.055 исправлено много ошибок. Если он все еще не работает, пожалуйста, отправьте сообщение об ошибке по адресу http://d.puremagic.com/issues /.
Комментарии:
1. Спасибо! Похоже, вы правы. После обновления поведение стало нормальным (по крайней мере, пока).