[armedbear-devel] Pure threads and hashtables test
Alan Ruttenberg
alanruttenberg at gmail.com
Sat Sep 28 15:48:17 UTC 2013
Ooh good catch! I have such an issue in my thread-per-jar function, the variable f which is bound in the loop, closed over in the thread run function but executed in a thread! That could explain both the missing values and the duplicates one. I'll report back.
Thanks!
Alan
-Alan
http://alan.ruttenbergs.com/
On Sat, Sep 28, 2013 at 11:44 AM, Pascal J. Bourguignon
<pjb at informatimago.com> wrote:
> Mark Evenson <evenson at panix.com> writes:
>> On Sep 27, 2013, at 9:28 PM, Mark Evenson <evenson at panix.com> wrote:
>>
>>>
>>> On Sep 27, 2013, at 8:13 PM, "Alan Ruttenberg" <alanruttenberg at gmail.com> wrote:
>>>
>>>> Agreed. While the gethash and puthash should independently work,
>>>> the combination of the two isn't thread safe. For example two
>>>> processes could get the value in the ht before either has a chance
>>>> to write back the increment.
>>>
>>> A version that only adds to unique keys in the hash table, relying
>>> on the HASH-TABLE-COUNT value to indicate successful update. The
>>> keys are the squares of the first eight primes, so the total threads
>>> spawned is eight. the parameter to RUN now indicates how many
>>> squares of the given prime basis. But still weirdness, in that the
>>> first thread which should increment the keys of the hashtable
>>> indexed by the powers of 2 doesn't seem to execute. Something in my
>>> LOOP clause?
>>>
>>> <threaded-hash.lisp>
>>
>> Indeed a faulty understanding of LOOP:
>>
>> CL-USER> (loop :for n :in '(2 3 5 7 11 13 15 17) :doing (threads:make-thread (lambda () (format t "~A " n))))
>>
>> 3 5 7 11 13 15 17
>> 17 NIL
>>
>> The value of "n" has already been incremented past the first member of the list when the closure is created with LAMBDA, so the thread with "2" never gets executed.
>>
>> SLIME users: one needs to place the form (setf
>> swank:*globally-redirect-io* t) in ~/.swank.lisp to get all the FORMAT
>> output in the REPL buffer. Otherwise look in the corresponding
>> *inferior-lisp* buffer.
>>
>> So, I guess one should loop over closures that have been correctly
>> initialized with the right values in some other manner. I'd go for
>> using DO over LOOP for unless someone can correct my understanding.
>> Either that, or I need to follow macro expansions.
> DO won't help better. For LOOP, DOTIMES, DOLIST, it's unspecified
> whether the variables are new bindings or updated bindings. But for DO
> and DO*, it is specified they're updated. So while with the former you
> had a chance for it to work (not conformingly), you stand no such chance
> with DO.
> What you must write is:
> (ql:quickload :bordeaux-threads)
> (loop :for n :in '(2 3 5 7 11 13 15 17)
> :do (let ((n n))
> (bt:make-thread (lambda () (format t "~A " n)))))
> (do ((ns '(2 3 5 7 11 13 15 17) (cdr ns)))
> ((null ns))
> (let ((n (car ns)))
> (bt:make-thread (lambda () (format t "~A " n)))))
> --
> __Pascal Bourguignon__
> http://www.informatimago.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20130928/34e7a65f/attachment.html>
More information about the armedbear-devel
mailing list