Obedient threads
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Oct 2 11:08:40 PDT 2014
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 at 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
More information about the Digitalmars-d-learn
mailing list