www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - thread exceptions

reply Martin Krejcirik <mk-junk i-line.cz> writes:
Hi,

using std.concurrency, is it possible to print an exception if a thread
throws (and the main thread is still running) ? It just terminates and
prints nothing. I tried to catch it and send as a message to the main
thread, but haven't succeeded so far.

-- 
mk
Aug 07 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/07/2012 06:25 PM, Martin Krejcirik wrote:
 Hi,

 using std.concurrency, is it possible to print an exception if a thread
 throws (and the main thread is still running) ? It just terminates and
 prints nothing. I tried to catch it and send as a message to the main
 thread, but haven't succeeded so far.

Here is an excerpt from a yet-unpublished change to my Concurrency chapter: ----- The OwnerTerminated and LinkTerminated exceptions can be received as messages as well. The following code demonstrates this for the OwnerTerminated exception: bool isDone = false; while (!isDone) { receive( (int message) { writeln("Message: ", message); } , (OwnerTerminated exc) { writeln("The owner has terminated; exiting."); isDone = true; } ); } ----- In order to receive LinkTerminated as a message, start the worker with spawnLinked() instead of spawn(). Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Aug 07 2012
next sibling parent reply Martin Krejcirik <mk-junk i-line.cz> writes:
Hi Ali,

On 8.8.2012 5:36, Ali Çehreli wrote:
 The OwnerTerminated and LinkTerminated exceptions can be received as
 messages as well. The following code demonstrates this for the
 OwnerTerminated exception:

I meant how can I print the actual exception from the thread, including it's error message, stack trace etc. Consider code like this, it just ends without any error message: import std.concurrency, std.stdio; void main() { writeln("main start"); spawn(&child); for (int i=0; i<1_000_000_000; i++) {}; writeln("main end"); } void child() { writeln("thread start"); for (int i=0; i<100_000; i++) {}; writeln("thread end"); throw new Exception("exception from thread"); } If I use spawnLinked, I know the thread ended, but still no original exception. If I change main() to terminate before child(), it actually waits until the child finishes and prints the exception, so there has to be a way. -- mk
Aug 08 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/08/2012 01:52 AM, Martin Krejcirik wrote:

 I meant how can I print the actual exception from the thread, including
 it's error message, stack trace etc.

Catching the exception explicitly and rethrowing would help a little: // ... at the worker ... try { // ... } catch (shared(Exception) exc) { owner.send(exc); }}, // ... at the owner ... receive( // ... (shared(Exception) exc) { throw exc; }); Although, I've been bitten by the fact that AssertError is not an Exception, so exceptions thrown by assert checks will continue to surprise. :/ Ali
Aug 08 2012
parent reply Martin Krejcirik <mk-junk i-line.cz> writes:
On 8.8.2012 18:15, Ali Çehreli wrote:
                 } catch (shared(Exception) exc) {
                     owner.send(exc);

Ahh shared, I've been trying immutable and such. Thanks a lot.
 
 Although, I've been bitten by the fact that AssertError is not an
 Exception, so exceptions thrown by assert checks will continue to
 surprise. :/

Easy, just catch Throwable :-) cya -- mk
Aug 08 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/08/2012 12:44 PM, Martin Krejcirik wrote:

 Easy, just catch Throwable :-)

The problem is, Error (and Throwable) should not be caught. There is no guarantee of program behavior when an Error is thrown. At the least, an AssertError is by definition pointing at bad program state so no further action should make sense. On the other hand, in my case catching by Throwable was the only way I could figure out why my concurrency program was getting stuck. So yeah, I guess the guideline should be don't catch Error in general. :) Ali
Aug 08 2012
prev sibling next sibling parent Sean Kelly <sean invisibleduck.org> writes:
I'll have to think about it. The current approach in std.concurrency is inte=
nded to be forwards-compatible with interprocess messaging, and serializing/=
deserializing an arbitrary exception would be tricky. See the exception thro=
wn by receiveOnly as an example of how I addressed the issue there.=20

On Aug 8, 2012, at 1:52 AM, Martin Krejcirik <mk-junk i-line.cz> wrote:

 Hi Ali,
=20
 On 8.8.2012 5:36, Ali =C3=87ehreli wrote:
 The OwnerTerminated and LinkTerminated exceptions can be received as
 messages as well. The following code demonstrates this for the
 OwnerTerminated exception:

I meant how can I print the actual exception from the thread, including it's error message, stack trace etc. Consider code like this, it just ends without any error message: =20 import std.concurrency, std.stdio; =20 void main() { writeln("main start"); spawn(&child); for (int i=3D0; i<1_000_000_000; i++) {}; writeln("main end"); } =20 void child() { writeln("thread start"); for (int i=3D0; i<100_000; i++) {}; writeln("thread end"); throw new Exception("exception from thread"); } =20 If I use spawnLinked, I know the thread ended, but still no original exception. If I change main() to terminate before child(), it actually waits until the child finishes and prints the exception, so there has to be a way. =20 --=20 mk

Aug 08 2012
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
Oh, I should mention that if you use core.thread explicitly, any unhandled e=
xception will be re-thrown in the context of whoever joins that thread.=20

On Aug 8, 2012, at 1:52 AM, Martin Krejcirik <mk-junk i-line.cz> wrote:

 Hi Ali,
=20
 On 8.8.2012 5:36, Ali =C3=87ehreli wrote:
 The OwnerTerminated and LinkTerminated exceptions can be received as
 messages as well. The following code demonstrates this for the
 OwnerTerminated exception:

I meant how can I print the actual exception from the thread, including it's error message, stack trace etc. Consider code like this, it just ends without any error message: =20 import std.concurrency, std.stdio; =20 void main() { writeln("main start"); spawn(&child); for (int i=3D0; i<1_000_000_000; i++) {}; writeln("main end"); } =20 void child() { writeln("thread start"); for (int i=3D0; i<100_000; i++) {}; writeln("thread end"); throw new Exception("exception from thread"); } =20 If I use spawnLinked, I know the thread ended, but still no original exception. If I change main() to terminate before child(), it actually waits until the child finishes and prints the exception, so there has to be a way. =20 --=20 mk

Aug 08 2012