digitalmars.D.learn - Strange exception using threads
- Minas Mina (80/80) Jun 23 2012 I am using a secondary thread to send messages to it so it can
- simendsjo (63/138) Jun 23 2012 You can notify child threads that their owner terminates so they can
- simendsjo (2/3) Jun 23 2012 auto tid = spawn(&writer); of course
- Sean Kelly (3/8) Jun 24 2012 With spawnLinked the child will send a termination message to the parent...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (33/36) Jun 23 2012 The OwnerTerminated exception is thrown when a worker attempts to
- simendsjo (2/13) Jun 23 2012 Nice. I thought you had to send an explicit message.
- Minas Mina (2/2) Jun 23 2012 Thank you very much :)
I am using a secondary thread to send messages to it so it can
print those messages.
import std.stdio;
import std.concurrency;
void main()
{
auto low = 0, high = 10;
auto tid = spawn(&writer);
foreach(i; low..high)
{
writeln("Main thread: ", i);
tid.send(tid, i);
}
}
void writer()
{
while( true )
{
receive(
(Tid id, int i)
{
writeln("Secondary thread: ", i);
}
);
}
}
This is the result:
Main thread: 0
Main thread: 1
Main thread: 2
Main thread: 3
Main thread: 4
Main thread: 5
Main thread: 6
Main thread: 7
Main thread: 8
Main thread: 9
Secondary thread: 0
Secondary thread: 1
Secondary thread: 2
Secondary thread: 3
Secondary thread: 4
Secondary thread: 5
Secondary thread: 6
Secondary thread: 7
Secondary thread: 8
Secondary thread: 9
std.concurrency.OwnerTerminated std/concurrency.d(248): Owner
terminated
----------------
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void
function(std.concurrency.Tid, int)*).get(scope void
function(std.concurrency.Tid, int)*).bool onControlMsg(ref
std.concurrency.Message)+0x2a) [0x437016]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void
function(std.concurrency.Tid, int)*).get(scope void
function(std.concurrency.Tid, int)*).bool scan(ref
std.concurrency.List!(std.concurrency.Message).List)+0x68)
[0x437084]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void
function(std.concurrency.Tid, int)*).get(scope void
function(std.concurrency.Tid, int)*)+0x88) [0x436c20]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
std.concurrency.receive!(void function(std.concurrency.Tid,
int)*).receive(void function(std.concurrency.Tid, int)*)+0x32)
[0x436b86]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
main.writer()+0x13) [0x43066b]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(_D3std11concurrency11__T6_spawnZ6_spawnFbPFZvZS3std11concurrenc
3Tid4execMFZv+0x45)
[0x430941]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
core.thread.Thread.run()+0x2a) [0x4470fe]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(thread_entryPoint+0xf3)
[0x446e97]
The program runs correctly but then boom! Does anyone know why?
Jun 23 2012
On Sat, 23 Jun 2012 18:05:47 +0200, Minas Mina
<minas_mina1990 hotmail.co.uk> wrote:
I am using a secondary thread to send messages to it so it can print
those messages.
import std.stdio;
import std.concurrency;
void main()
{
auto low = 0, high = 10;
auto tid = spawn(&writer);
foreach(i; low..high)
{
writeln("Main thread: ", i);
tid.send(tid, i);
}
}
void writer()
{
while( true )
{
receive(
(Tid id, int i)
{
writeln("Secondary thread: ", i);
}
);
}
}
This is the result:
Main thread: 0
Main thread: 1
Main thread: 2
Main thread: 3
Main thread: 4
Main thread: 5
Main thread: 6
Main thread: 7
Main thread: 8
Main thread: 9
Secondary thread: 0
Secondary thread: 1
Secondary thread: 2
Secondary thread: 3
Secondary thread: 4
Secondary thread: 5
Secondary thread: 6
Secondary thread: 7
Secondary thread: 8
Secondary thread: 9
std.concurrency.OwnerTerminated std/concurrency.d(248): Owner terminated
----------------
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void function(std.concurrency.Tid,
int)*).get(scope void function(std.concurrency.Tid, int)*).bool
onControlMsg(ref std.concurrency.Message)+0x2a) [0x437016]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void function(std.concurrency.Tid,
int)*).get(scope void function(std.concurrency.Tid, int)*).bool scan(ref
std.concurrency.List!(std.concurrency.Message).List)+0x68) [0x437084]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(bool
std.concurrency.MessageBox.get!(void function(std.concurrency.Tid,
int)*).get(scope void function(std.concurrency.Tid, int)*)+0x88)
[0x436c20]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
std.concurrency.receive!(void function(std.concurrency.Tid,
int)*).receive(void function(std.concurrency.Tid, int)*)+0x32) [0x436b86]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
main.writer()+0x13) [0x43066b]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(_D3std11concurrency11__T6_spawnZ6_spawnFbPFZvZS3std11concurrenc
3Tid4execMFZv+0x45)
[0x430941]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(void
core.thread.Thread.run()+0x2a) [0x4470fe]
/home/minas/Projects/D/D_Test/D_Test/bin/Debug/D_Test(thread_entryPoint+0xf3)
[0x446e97]
The program runs correctly but then boom! Does anyone know why?
You can notify child threads that their owner terminates so they can
finish up
import std.stdio;
import std.concurrency;
void main()
{
auto low = 0, high = 10;
auto tid = spawnLinked(&writer);
foreach(i; low..high)
{
writeln("Main thread: ", i);
tid.send(tid, i);
}
writeln("need to gracefully terminate child threads");
tid.send(tid, Term());
writeln("term sent");
}
struct Term {}
void writer()
{
bool done;
while( !done )
{
receive(
(Tid id, int i)
{
writeln("Secondary thread: ", i);
},
(Tid id, Term term)
{
writeln("Owner terminated, so do we");
done = true;
}
);
}
}
Main thread: 0
Main thread: 1
Main thread: 2
Main thread: 3
Main thread: 4
Secondary thread: 0
Secondary thread: 1
Secondary thread: 2
Secondary thread: 3
Secondary thread: 4
Main thread: 5
Main thread: 6
Main thread: 7
Main thread: 8
Main thread: 9
Secondary thread: 5
Secondary thread: 6
need to gracefully terminate child threads
term sent
Secondary thread: 7
Secondary thread: 8
Secondary thread: 9
Owner terminated, so do we
Jun 23 2012
On Sat, 23 Jun 2012 18:29:37 +0200, simendsjo <simendsjo gmail.com> wrote:auto tid = spawnLinked(&writer);auto tid = spawn(&writer); of course
Jun 23 2012
On Jun 23, 2012, at 9:31 AM, simendsjo <simendsjo gmail.com> wrote:On Sat, 23 Jun 2012 18:29:37 +0200, simendsjo <simendsjo gmail.com> wrote:==20With spawnLinked the child will send a termination message to the parent as w= ell.=auto tid =3D spawnLinked(&writer);=20 auto tid =3D spawn(&writer); of course
Jun 24 2012
On 06/23/2012 09:05 AM, Minas Mina wrote:I am using a secondary thread to send messages to it so it can print those messages.std.concurrency.OwnerTerminated std/concurrency.d(248): Owner terminatedThe OwnerTerminated exception is thrown when a worker attempts to receive a message to notify it about the fact that its owner has been terminated. There are ways to deal with the situation: - The worker can catch this particular exception - The worker can catch this exception as a message - The owner can send a special YouAreDone :) message to the worker so it no longer attempts to receive messages and exits gracefully - More? Here is the second method as described in TDPL's concurrency chapter, which is available online: http://www.informit.com/articles/article.aspx?p=1609144 void writer() { bool done = false; while( !done ) { receive( (Tid id, int i) { writeln("Secondary thread: ", i); }, (OwnerTerminated exc) // <----- as a message { done = true; } ); } } Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Jun 23 2012
On Sat, 23 Jun 2012 18:29:50 +0200, Ali =C3=87ehreli <acehreli yahoo.com=wrote:receive( (Tid id, int i) { writeln("Secondary thread: ", i); }, (OwnerTerminated exc) // <----- as a message { done =3D true; } );Nice. I thought you had to send an explicit message.
Jun 23 2012
Thank you very much :) I like the "you are done :)" approach!
Jun 23 2012









Sean Kelly <sean invisibleduck.org> 