www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange exception using threads

reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
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
next sibling parent simendsjo <simendsjo gmail.com> writes:
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
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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 terminated

The 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
prev sibling next sibling parent simendsjo <simendsjo gmail.com> writes:
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
prev sibling next sibling parent simendsjo <simendsjo gmail.com> writes:
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
prev sibling next sibling parent "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
Thank you very much :)

I like the "you are done :)" approach!
Jun 23 2012
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
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:=

=20
    auto tid =3D spawnLinked(&writer);

auto tid =3D spawn(&writer); of course

With spawnLinked the child will send a termination message to the parent as w= ell.=
Jun 24 2012