[Openmcl-devel] Slime / CCL interaction: random returning the same value
R. Matthew Emerson
rme at clozure.com
Mon Dec 14 10:19:21 PST 2009
On Dec 13, 2009, at 7:24 PM, Patrick May wrote:
> Hi,
>
> I raised the following issue on the Slime mailing list and got a couple of helpful responses that at least explained why I was seeing what I was seeing:
>
>>>>> I'm using Slime in Aquamacs with CCL. When I evaluate (random
>>>>> 100) repeatedly in CCL started from a shell, I get a randomly
>>>>> generated number between 0 and 99 inclusive. When I do the same with
>>>>> C-x C-e within Slime, I get the same number every time. (random 100
>>>>> (make-random-state)) gives the same behavior, but
>>>>> (random 100 (make-random-state t)) works properly.
>>>>>
>>>>> Is Slime caching something or have I hosed up my environment?
>>>>
>>>> Sorry for the late response. CCL's swank backend uses threads by
>>>> default, and threads inherit values from the global
>>>> environment. *RANDOM-STATE* probably becomes thread-local automatically
>>>> in CCL, resulting in the behaviour you described.
>>>>
>>>> It should work when you type in the form at the Slime REPL which
>>>> evaluates all forms in the same thread.
>
> Some poking around with the Slime documentation shows that I can change swank:*communication-style* from :SPAWN to :SIGIO or :FD-HANDLER to avoid this issue, but :SIGIO has some caveats associated with it.
>
> Is there a way to make the random state not thread local?
Well, not really; at least not in the sense of being able to say something like
(setq ccl:*random-state-and-threads-dwim* t).
*random-state* is mutated every time you call RANDOM. If it were not thread-local, then there would have to be some sort of lock or other mechanism to prevent *random-state* from being modified by more than one thread at a time.
Depending on your application, it might be reasonable to implement something like this yourself, e.g.
(defvar *my-random-state* (make-random-state t))
(defvar *my-random-state-lock* (make-lock))
(defun my-random (n)
(with-lock-grabbed (*my-random-state-lock*)
(random n *my-random-state*)))
Or something like that (code typed in mail).
More information about the Openmcl-devel
mailing list