Multiple Threads Crash
[1/11] from: sanghabum:aol at: 23-Jul-2001 19:01
Hi all,
The code below is something I started writing to get a feel for Rebol's
undocumented concurrent and muti-threading capabilities, and to verify where
and what sort of serialisation code I need to build into my applications.
(Jeff will be pleased to know that I had it in my mind to turn my discoveries
into a Zine article).
Unfortunately, it's crash prone. If I click the buttons furiously, it crashes
(Win 98) with a "Rebol has performed an illegal operation..." message at
around 70-80 active threads.
If I click a bit more sedately to keep the thread level around 50 or so, it
soon crashes with a Rebol console error: "Invalid data type during recycle **
Press enter to quit..."
Two questions for anyone out there interested:
1. Is it a Windows problem, or a fault with Rebol (View 1.2.1.3.1
21-Jun-2001)?
2. If been ticked off before for "DO"ing a string and have tried to mend my
ways. But I don't see a straightforward way of avoiding it this time. Any
suggestions.
--Thanks as usual,
--Colin.
=======================
Rebol [title: "multi threads test"]
Threads-Count: 0
ChangeBoxes: func [new-color [String!]
speedfactor [Integer!] /local nn ] [
BumpThreads 1
print ["Go " new-color " started"]
for nn 1 20 1
[
do join "box-" [nn "/color: " New-Color]
do join "show box-" nn
wait random (speedfactor / 200)
] ; for
print ["Go " new-color " ended"]
BumpThreads -1
return true
] ; fund
BumpThreads: func [n [integer!]] [
Threads-Count: Threads-Count + n
Threads-on-the-go/Text: Threads-Count
Show Threads-on-the-go
] ; func
testlayout: layout [
across
box-1: box 50x50 red
box-2: box 50x50 red
box-3: box 50x50 red
box-4: box 50x50 red
box-5: box 50x50 red
return
box-6: box 50x50 red
box-7: box 50x50 red
box-8: box 50x50 red
box-9: box 50x50 red
box-10: box 50x50 red
return
box-11: box 50x50 red
box-12: box 50x50 red
box-13: box 50x50 red
box-14: box 50x50 red
box-15: box 50x50 red
return
box-16: box 50x50 red
box-17: box 50x50 red
box-18: box 50x50 red
box-19: box 50x50 red
box-20: box 50x50 red
return
threads-on-the-go: info 50x50 Center Middle font-size 20
Return
Button "go Blue" [ChangeBoxes "blue" 5]
Button "go Yellow" [ChangeBoxes "Yellow" 10]
Button "go White" [ChangeBoxes "White" 12]
Return
Button "go Red" [ChangeBoxes "Red" 15]
Button "go Pink" [ChangeBoxes "Pink" 2]
Button "go Green" [ChangeBoxes "Green" 1]
]
unview/all
View testlayout
halt
=======================
(if you have a faster/slower machine, you may need to adjust the timing
factors).
[2/11] from: bard::papegaaij::austarnet::com::au at: 24-Jul-2001 9:27
Hi Colin,
Just tested your program on my Win2K machine and it crashed just above the
55 mark with the "Invalid data type during recycle" message.
Regards,
Bard
[3/11] from: joel:neely:fedex at: 23-Jul-2001 18:38
Hi, Colin,
[Sanghabum--aol--com] wrote:
> 2. If been ticked off before for "DO"ing a string and have
> tried to mend my ways. But I don't see a straightforward wa
> of avoiding it this time. Any suggestions.
>
Yes. Put your boxes in a block and iterate across that. One
quick-and-dirty way to do it is as follows:
8<------------------------------------------------------------
boxcol: make object! [
Threads-Count: 0
boxes: []
ChangeBoxes: func [
new-color [tuple!] speedfactor [Integer!]
/local nn
][
BumpThreads 1
print ["Go " new-color " started"]
foreach a-box boxes [
a-box/color: new-color
show a-box
wait random (speedfactor / 200)
]
print ["Go " new-color " ended"]
BumpThreads -1
return true
]
BumpThreads: func [n [integer!]] [
Threads-Count: Threads-Count + n
Threads-on-the-go/Text: Threads-Count
Show Threads-on-the-go
]
testlayout: layout [
across
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
return
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
return
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
return
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
a-box: box 50x50 red do [append boxes a-box]
return
threads-on-the-go: info 50x50 Center Middle font-size 20
Return
Button "go Blue" [ChangeBoxes blue 5]
Button "go Yellow" [ChangeBoxes yellow 10]
Button "go White" [ChangeBoxes white 12]
Return
Button "go Red" [ChangeBoxes red 15]
Button "go Pink" [ChangeBoxes pink 2]
Button "go Green" [ChangeBoxes green 1]
]
]
unview/all
view boxcol/testlayout
halt
8<------------------------------------------------------------
--
This sentence contradicts itself -- no actually it doesn't.
-- Doug Hofstadter
joel<dot>neely<at>fedex<dot>com
[4/11] from: sanghabum:aol at: 23-Jul-2001 19:48
[bard--papegaaij--austarnet--com--au]:
> Just tested your program on my Win2K machine and it crashed just above the
> 55 mark with the "Invalid data type during recycle" message.
Rebol is nothing if not consistent!
Thanks,
Colin.
[5/11] from: joel:neely:fedex at: 23-Jul-2001 18:42
Hi, Bard and Colin,
Bard Papegaaij wrote:
> Hi Colin,
>
> Just tested your program on my Win2K machine and it crashed
> just above the 55 mark with the "Invalid data type during
> recycle" message.
>
Just tested on *my* w2k box, with an even weirder result!
When the counter hit 142, I got the message below:
=======================================================================
** Script Error: all expected block argument of type: ?object? show 0x0
none
none
** Where: wake-event
** Near: all [face/state face/texts face/text: any [face/texts/2
face/texts/1
]]
state: either not
=======================================================================
???
-jn-
--
This sentence contradicts itself -- no actually it doesn't.
-- Doug Hofstadter
joel<dot>neely<at>fedex<dot>com
[6/11] from: sanghabum:aol at: 23-Jul-2001 20:03
[joel--neely--fedex--com]:
> > 2. If been ticked off before for "DO"ing a string and have
> > tried to mend my ways. But I don't see a straightforward wa
> > of avoiding it this time. Any suggestions.
> >
>
> Yes. Put your boxes in a block and iterate across that. One
> quick-and-dirty way to do it is as follows:
>
Clever!, Thanks Joe.
And, for me, running you version gets us a fourth failure message, one I've
not seen since Core 2.3:
Crash (should not happen) Corrupt data type 232
--Colin.
[7/11] from: arolls:bigpond:au at: 24-Jul-2001 20:56
> Unfortunately, it's crash prone. If I click the buttons
> furiously, it crashes
<<quoted lines omitted: 5>>
> during recycle **
> Press enter to quit..."
I got your two errors on win2k.
To reduce the code below a bit:
lay: copy []
loop 4 [
loop 5 [
append lay [a-box: box 50x50 red do [append boxes a-box]]
]
append lay 'return
]
> testlayout: layout [
> across
<<quoted lines omitted: 22>>
> box-20: box 50x50 red
> return
Then append the rest of this to lay:
[8/11] from: holger:rebol at: 24-Jul-2001 9:40
On Mon, Jul 23, 2001 at 07:01:00PM -0400, [Sanghabum--aol--com] wrote:
> Hi all,
>
> The code below is something I started writing to get a feel for Rebol's
> undocumented concurrent and muti-threading capabilities, and to verify where
> and what sort of serialisation code I need to build into my applications.
Calling 'wait from within an awake handler is not really supported. It is
bad style anyway, because in event-driven systems event handlers are not
allowed to block. That's because blocking in an event handler makes programs
extremely difficult to debug, in particular if the list of handlers (meaning,
faces) is modified while another handler is suspended. The problem is that
all those suspended handlers carry hidden "context" around with them, and
you might end up with an "old" handler being woken up from suspension after
the face it has been associated with has already been removed from the
pane, by a different handler. Other complications are possible, as well. It
is extremely difficult to foresee all of these side effects, so programs that
use tricks like that are bound to be buggy and full of race conditions.
As for the crashes, this is the result of a limit on recursion in current REBOL
versions. Should be eliminated in one of the next version.
--
Holger Kruse
[holger--rebol--com]
[9/11] from: sanghabum:aol at: 24-Jul-2001 14:41
[Holger--rebol--com] writes:
> > The code below is something I started writing to get a feel for Rebol's
> > undocumented concurrent and muti-threading capabilities, and to verify
> where
> > and what sort of serialisation code I need to build into my
applications.
> Calling 'wait from within an awake handler is not really supported. It is
> bad style anyway, because in event-driven systems event handlers are not
> allowed to block.
<snip>
Thanks for the detail reply, Holger.
I appreciate the design problems, but let me make a "business case" for
needing to issue a wait within a VID action facet.
I'm developing an application that has "forward" and "backward" buttons to
move the user through a structured set of panels. But some users have very
slow machines and some panels need an appreciable amount of time to display.
So (after consulting the list: "[REBOL] Re: Interrupting an action") I added
a "Break" button and put a wait 0 & check for Cancel-requested Flag in the
Forward and Backward buttons' action facets.
It was then I realised that my "forward" and "backward" buttons could be
pressed repeatedly with each initiating a concurrent action. As they were all
competing to update a common panel the results got visually
interesting--though operationally useless. I added an "in use" flag to block
the unwanted threads and wrote the code that started this List Thread as a
way of exploring the behavior in a simplified form.
The operational code appears to work fine. At any one time there is only one
action facet updating the panel, with frequent "wait 0" and checks on the
Cancel-requested Flag. If this code is suspect for the reasons you give, can
you suggest another, perhaps more Rebelious, approach?
--Thanks,
--Colin.
[10/11] from: g:santilli:tiscalinet:it at: 25-Jul-2001 18:54
Hello Holger!
On 25-Lug-01, you wrote:
HK> Calling 'wait from within an awake handler is not really
HK> supported. It is bad style anyway, because in event-driven
What happens when we call INFORM inside a button action? And if we
download something inside a button action? I think we've always
been using WAIT inside actions etc., even if myabe indirectly;
wasn't this issue taken into consideration when switching to the
new event model?
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[11/11] from: petr:krenzelok:trz:cz at: 26-Jul-2001 6:18
Gabriele Santilli wrote:
> Hello Holger!
> On 25-Lug-01, you wrote:
<<quoted lines omitted: 5>>
> wasn't this issue taken into consideration when switching to the
> new event model?
I don't know if it is related or not, but I already reported /Pro
version problems using call/wait in button action block. Sometimes it
crashes, sometimes it doesn't ...
I just hope we will get the top super ultra cool event/tasking/threading
system one day :-) We are not so much far away - View is single threaded
and look what can be achieved by clever event handling. We just need
more non-blocking, async behavior, and RT expressed their will to
support us with async protocols in some possibly not so distant future.
I hope more port types will come "waitable - non-blocking" (e.g. ODBC
..)
-pekr-
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted