开发者

Strange behavior with 'setMaxMailboxSize'

开发者 https://www.devze.com 2023-04-12 06:17 出处:网络
I\'ve written a simple, though highly multi-threaded, prime numbers generator. The algorithm goes like this:

I've written a simple, though highly multi-threaded, prime numbers generator. The algorithm goes like this: Thread 0: generates consecutive numbers. Threads 1 .. N: filter out numbers that are not prime. Upon each 'new' prime discovery, a new filter thread is added.

Take I: no flow control at all. Thread 0 'send's numbers absolutely freely. The program finishes with signal 11 (seg. fault), rarely signal 8, even more rarely finishes successfully.

Take II: flow control with 'setMaxMailboxSize' to 1. Most of the time, everything works well.

Take III: Now, if it all was a result of some internal unheld overflow, it should do well with 'setMax开发者_C百科MailboxSize' to 2 (or even 10), am I wrong ? Thread 0 becomes stuck after it blocks for the first time.

Could someone please direct me what do I miss ?

Note 1: I use DMD v2.053 under Ubuntu 10.04

Note 2: This is my code:

#!/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);
                }
            }
        );
    }
}


Sounds like a bug in std.concurrency. Try upgrading DMD to 2.055. I'm not sure if this specific bug is fixed but there are a lot of bug fixes between 2.053 and 2.055. If it's still broken then please file a bug report at http://d.puremagic.com/issues/.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号