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