On Mon, 22 Aug 2005 07:32:29 +0300 (EEST), Nikodemus Siivola <nikodemus@...> said:
> On Sun, 21 Aug 2005, Christopher Neufeld wrote:
>> (defun main ()
>> (dotimes (i 100)
>> (sb-thread:make-thread #'(lambda () (worker i)))))
>> The output of (main) should be the integers from 0 to 99, not necessarily
>> in order. Instead, a typical run will produce the number 13 seven times,
>> then the number 20 seven times, then the number 27 seven times, then the
>> number 33 twelve times, and so on.
> Right on mark up till this point. However, the solution is much simpler:
> (defun main ()
> (dotimes (i 100)
> (let ((ti i))
> (sb-thread:make-thread #'(lambda () (worker ti))))))
> ...introduce a separate binding for each thread. (Untested, not having
> an x86 Linux handy.)
Actually, this seemed like a natural thing to try, and I tried it in my
testing. It did cause the symptoms to disappear. However, as there was no
documentation guaranteeing this behaviour, I didn't want to count on it, in
case some more subtle bug was going on here. Just because a race condition
seems to disappear, doesn't mean it's fixed.
Anyway, I'm happy with the behaviour, if it can be documented. The
construct I provided seemed natural, and almost did the right thing, but
the documentation should reflect that a new closure should be created
holding all of the mutable context used in the call. It's clear on
reflection why this is the case, but it's a classic gotcha, and one that
introduces subtle, non-reproducble errors if not fully grasped.
By the way, the serialization I put in with a mutex and condition variable
to get around the problem of my variables shifting underneath me actually
speeded up the creation of my swarm of 500 threads by more than a factor of
two over creating a new closure. This was for my contribution to the
threads-flow shootout benchmark. Apparently, for this combination of
kernel and sbcl versions, the galloping threads got in each others ways.
On Mon, 22 Aug 2005 12:27:01 +0200, =?iso-8859-1?q?G=E1bor_Melis?= <mega@...> said:
> LIST-ALL-THREADS lists all active threads. Finished threads are not
> listed but they may be around waiting for a gc to reap them. The
> problem is that creating new threads does not use the normal allocation
> mechanism and does not necessarily trigger gc. If instead of sleeping
> you called (gc) then the threads would be gc'ed.
> Well, at least that's the clumsy expected behaviour that was broken
> recently. I checked in 0.9.3.75 that fixes the gc so the above
> paragraph stands.
OK, thanks. My checkout from last night does not have that fix, I'll check
it out later.
Home page: http://www.cneufeld.ca/neufeld
"Don't edit reality for the sake of simplicity"