On 10/02/2014 06:49 AM, Chris wrote:
On Thursday, 2 October 2014 at 13:05:00 UTC, ketmar via
Digitalmars-d-learn wrote:
On Thu, 02 Oct 2014 11:36:06 +0000
Chris via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

you can use receiveTimeout! to check if there is some message available.

That won't do. It blocks the main thread too (for the duration of
timeout), and it might abandon the thread too early. If you do it like
in Ali's example[1], the main thread is blocked in the sense that it
does not listen to input.

[1] http://ddili.org/ders/d.en/concurrency.html

To add to what ketmar said, even 0.msecs works.

In such a case moving the other tasks out of the main thread may be a better option. main can safely block on the message queue while another thread interacts with the outside world. It would be a cleaner event loop that way.

I've just improved that example to interact with the user. The worker produces a random message periodically. The user can ask for the most recent message by entering "yes". (I made it so that reading the message also clears it.)

import std.stdio;
import std.concurrency;
import core.thread;
import std.string;
import std.random;
import std.array;

void workerFunc(size_t count, Duration duration)
{
    writefln("There will be %s messages every %s.", count, duration);

    foreach (i; 0 .. count) {
        Thread.sleep(duration);
        ownerTid.send(format("message %s: %s", i, uniform(0, 100)));
    }

    writeln("workerFunc exiting");
}

struct ResultPlease
{}

void interactor()
{
    bool done = false;

    while (!done) {
        write("Would you like to see the result? ");
        string response = readln.chomp;

        if (response == "yes") {
            ownerTid.send(ResultPlease(), thisTid);
            const result = receiveOnly!string();

            if (result.empty) {
                writeln("Sorry, no result yet.");

            } else {
                writefln(`The result is "%s"`, result);
            }

        } else {
            writeln("Ok, no more interaction. Bye.");
            done = true;
        }
    }
}

void main()
{
    spawnLinked(&workerFunc, 4, 5.seconds);
    spawnLinked(&interactor);

    string result;
    Tid[] completed;

    while (completed.length < 2) {
        receive(
            (string message) {
                result = message;
            },

            (ResultPlease request, Tid requestor) {
                requestor.send(result);
                result = "";
            },

            (LinkTerminated e) {
                completed ~= e.tid;
            }
        );
    }
}

Ali

Reply via email to