Hi, Torsten!

Though I don't think using exceptions is the best way to achieve what you
mean, let's tackle the general question first.

It's true that those exceptions will never get caught by any other thread
than the one it occurred in unless you explicitly do something about it.
For example:

proc {ExceptionInjectingThread P}
   Creator = {Thread.this}
in
   thread
      try
         {P}
      catch X then
         {Thread.injectException Creator X}
      end
   end
end

However, this would introduce race conditions, as you would be threatened
by a host of evil "child" threads likely to inject you with exceptions at
any time. For example, an exception might be injected exactly as you are
handling the first exception...

Here is a design that would do what you want:

fun {Spawner N F}
   Rslt
   Synch = {NewCell unit}
   Thrds = for I in 1..N
              collect:C
           do
              Child
           in
              thread
                 !Child = {Thread.this}
                 Candidate = {F}
                 Next
                 Cur = Synch := Next
              in
                 {Wait Cur}
                 if {IsFree Rslt} then
                    Rslt = rslt(Candidate)
                 end
                 Next = Cur
                 {Wait _}
              end
              {C Child}
           end
in
   {Wait Rslt}
   {ForAll Thrds Thread.terminate}
   Rslt.1
end

Cheers,

Jorge.

Torsten Anders wrote:
> Dear all,
>
> Sorry if I missed some section in the Oz documentation concerning
> this issue.
>
> How can I catch an exception raised in a (possibly nested) thread?
> Please consider the dummy example below, which is simply an edited
> version of an exception example in the tutorial. The difference is
> solely that Eval raises an exception from within a thread. As a
> consequence, it appears that the catch statement does never see this
> exception -- it is instead reported by the top-level.
>
> proc {Eval E}
>     thread
>        case E
>        of   plus(X Y) then {Browse X+Y}
>        []   times(X Y) then {Browse X*Y}
>        else raise illFormedExpression(E) end
>        end
>     end
> end
>
> try
>     {ForAll [plus(5 10) times(6 11) min(7 10)] Eval}
> catch
>     illFormedExpression(X) then {Browse '** '#X#' **'}
> end
>
>
> As I said, this is only a dummy example. What I actually want to do
> is terminating a number of threads after one of them found a result,
> and I though that raising an exception containing the result would be
> a clean technique. BTW: I also tried terminating all my threads
> explicitly (see code below). Yet this resulted in another exception
> -- namely kernel(deadThread ...) ...) -- and so I was looking for
> alternative solutions..
>
> {ForAll MyThreads Thread.terminate}
>
> Thank you!
>
> Best
> Torsten
>
> _________________________________________________________________________________
> mozart-users mailing list
> [email protected]
> http://www.mozart-oz.org/mailman/listinfo/mozart-users
>


_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to