Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane
From: Kevin Reid <kpreid <at> mac.com>
Subject: Re: Bug with dotimes() and make-thread()
Newsgroups: gmane.lisp.steel-bank.general
Date: Thursday 14th February 2008 17:52:48 UTC (over 8 years ago)
On Feb 14, 2008, at 12:30, [email protected] wrote:

> However, I've found a BUG that shows up in the following code.  
> Sometimes this snippet generates an erroneous result:
>
> ;; first run:
>
> CL-USER> (let ((res nil))
> 	   (dotimes (n 3)
> 	     (push (sb-thread:make-thread #'(lambda () (cons n n))) res))
> 	   (mapcar #'sb-thread:join-thread (reverse res)))
>
> ((0 . 0) (2 . 2) (3 . 3))
...
> ((0 . 0) (1 . 1) (2 . 2))
...
> ((0 . 0) (1 . 1) (3 . 3))

This is not a bug, but permitted behavior of DOTIMES. According to  
the CLHS:

"It is implementation-dependent whether dotimes establishes a new  
binding of var on each iteration or whether it establishes a binding  
for var once at the beginning and then assigns it on any subsequent  
iterations."

SBCL currently does the latter. Therefore, your three lambdas close  
over the same binding, which is the one being mutated by DOTIMES.

The variation you are seeing comes from the OS scheduler: whether the  
thread retrieves n before or after DOTIMES proceeds to its next  
iteration.

You can also see this type of behavior without threads:

(let ((res nil))
   (dotimes (n 3)
     (push (lambda () (cons n n)) res))
   (mapcar #'funcall (reverse res)))

This will always return ((3 . 3) (3 . 3) (3 . 3)).

One way to do this correctly is:

(dotimes (n 3)
   (let ((n n))
     (push (sb-thread:make-thread #'(lambda () (cons n n))))

This establishes a new, never-reassigned, binding for each closure.

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
 
CD: 3ms