digitalmars.D.learn - Mailbox limits and dead/livelocks?
- Enerqi (94/94) Jul 24 2012 The actors in std.concurrency - in this example it's
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (25/30) Jul 24 2012 I have struggled with a similar problem recently. When an apparent
- Enerqi (3/38) Jul 24 2012 Excellent, it was a rogue exception in another program that was
The actors in std.concurrency - in this example it's
non-deterministic whether the process may or may not hang. I'm
confused as to why. I have set the mailbox sizes to 1. But the
message flow seems simple enough. I don't see how the message
limit of 1 is blocking everything, I am catching Variant messages
so nothing should be in the mailbox unread.
----------
import core.thread;
import std.algorithm;
import std.concurrency;
import std.stdio;
int main(string[] args)
{
Tid[2] tids;
bool[Tid] response_flags;
for(auto i=0; i < 2; ++i)
{
tids[i] = spawn(&blah1, thisTid);
response_flags[tids[i]] = false;
}
auto receive_count = 0;
setMaxMailboxSize(thisTid, 1, OnCrowding.block);
while(! reduce!"a && b"(response_flags))
{
writeln(response_flags, " ", receive_count);
receive((Tid some_blah_id, int done)
{
assert(done == 42);
++receive_count;
response_flags[some_blah_id] = true;
},
(Variant v)
{
writeln("Unexpected message: ", v, " type ",
v.type());
}
);
}
return 0;
}
void blah1(Tid parent)
{
setMaxMailboxSize(thisTid, 1, OnCrowding.block);
auto subtid = spawn(&subsub, thisTid, parent);
send(subtid, thisTid, false);
receive((bool got)
{
assert(got);
},
(Variant v)
{
writeln("Unexpected message: ", v, " type ",
v.type());
});
send(subtid, thisTid, 10);
receive((int got)
{
assert(got == 11);
},
(Variant v)
{
writeln("Unexpected message: ", v, " type ",
v.type());
});
}
void subsub(Tid parent, Tid grandparent)
{
setMaxMailboxSize(thisTid, 1, OnCrowding.block);
receive((Tid parent, bool whatever)
{
assert(!whatever);
},
(Variant v)
{
writeln("Unexpected message: ", v, " type ",
v.type());
});
send(parent, true);
receive((Tid parent, int n)
{
assert(n == 10);
},
(Variant v)
{
writeln("Unexpected message: ", v, " type ",
v.type());
});
send(parent, 11);
send(grandparent, parent, 42);
}
----------
Cheers.
Jul 24 2012
On 07/24/2012 07:46 AM, Enerqi wrote:The actors in std.concurrency - in this example it's non-deterministic whether the process may or may not hang. I'm confused as to why. I have set the mailbox sizes to 1. But the message flow seems simple enough. I don't see how the message limit of 1 is blocking everything, I am catching Variant messages so nothing should be in the mailbox unread.I have struggled with a similar problem recently. When an apparent lock-up occurs, it may be because a worker has terminated, likely by assert(). (There has been a thread about exceptions from workers getting lost.) The trick is to start the worker with spawnLinked so that a LinkTerminated exception can be received on the owner's side: tids[i] = spawnLinked(&blah1, thisTid); // ... (LinkTerminated exc) { writeln("A worker has terminated: ", exc); // ... }, The other std.concurrency exception that can be received as a message is OwnerTerminated: (OwnerTerminated exc) { writeln("The owner has terminated; exiting."); isDone = true; } I am in the process of updating the following page with the information above: http://ddili.org/ders/d.en/concurrency.html Ali
Jul 24 2012
Excellent, it was a rogue exception in another program that was causing hangs and issues for me. Thanks :) On Tuesday, 24 July 2012 at 15:33:34 UTC, Ali Çehreli wrote:On 07/24/2012 07:46 AM, Enerqi wrote:The actors in std.concurrency - in this example it'snon-deterministicwhether the process may or may not hang. I'm confused as towhy. I haveset the mailbox sizes to 1. But the message flow seems simpleenough. Idon't see how the message limit of 1 is blocking everything,I amcatching Variant messages so nothing should be in the mailboxunread. I have struggled with a similar problem recently. When an apparent lock-up occurs, it may be because a worker has terminated, likely by assert(). (There has been a thread about exceptions from workers getting lost.) The trick is to start the worker with spawnLinked so that a LinkTerminated exception can be received on the owner's side: tids[i] = spawnLinked(&blah1, thisTid); // ... (LinkTerminated exc) { writeln("A worker has terminated: ", exc); // ... }, The other std.concurrency exception that can be received as a message is OwnerTerminated: (OwnerTerminated exc) { writeln("The owner has terminated; exiting."); isDone = true; } I am in the process of updating the following page with the information above: http://ddili.org/ders/d.en/concurrency.html Ali
Jul 24 2012








"Enerqi" <kelvin.d.ward googlemail.com>