Странное поведение с 'setMaxMailboxSize' - PullRequest
4 голосов
/ 09 октября 2011

Я написал простой, хотя и многопоточный генератор простых чисел. Алгоритм выглядит так: Поток 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);
                }
            }
        );
    }
}

1 Ответ

2 голосов
/ 09 октября 2011

Звучит как ошибка в std.concurrency.Попробуйте обновить DMD до 2.055.Я не уверен, исправлена ​​ли эта конкретная ошибка, но есть много исправлений ошибок между 2.053 и 2.055.Если он все еще не работает, отправьте отчет об ошибке на http://d.puremagic.com/issues/.

...