Re: [Chicken-users] srfi-18 threads question

2016-09-21 Thread John Cowan
On Wed, Sep 21, 2016 at 4:53 PM,  wrote:

> ;; Why does the mutation of a simple global in a thread become visible to
> the main thread, but the mutation of global parameter does not?
>
> In general, parameters are designed to be per-thread rather than shared.
If they weren't, the parameter wouldn't reliably maintain its value
throughout the dynamic scope of a parameterize form.  So when you attempt
to mutate a parameter from another thread, you are mutating a copy.

Specifically, a parameter that has been bound with parameterize is always
per-thread. As you can see by looking at SRFI 39's rationale, unbound
parameters can behave differently in different implementations.  Chicken
chooses to make them per-thread in all cases: parameters are just elements
of a hidden vector that is copied when a new thread is forked (which means
it's expensive to have millions of parameter objects).
___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] srfi-18 threads question

2016-09-21 Thread brandon
Hi All, 

New to this list and srfi-18 threads.  I want to make use of parameters
in a thread-safe way, but I have run into problems.  It seems to me that
parameters created in one thread cannot be manipulated in a persistent
way from another thread. Here is some example code showing what I mean: 

(use srfi-18) 

 ;; mutex-protect parameter 

(define (make-synchronized-parameter value) 

  (let ((mutex (make-mutex)) 

(param (make-parameter value))) 

(lambda args 

  (mutex-lock! mutex) 

  (let ((result (apply param args))) 

(mutex-unlock! mutex) 

result 

(define *safe-param* (make-synchronized-parameter #f)) (define
*unsafe-global* #f) 

(define (mutate-things) 

  (set! *unsafe-global* 42) 

  (*safe-param* 42) 

  (print "2thread> unsafe-global is "*unsafe-global*" safe-param is
"(*safe-param*)) 

  (thread-sleep! 2) ;; make global safe for test 

  (print "4thread> just before exit unsafe-global is "*unsafe-global*"
safe-param is "(*safe-param*))) 

(define (main) 

  (let* ((thread (make-thread mutate-things))) 

(print "1main> before thread-start unsafe-global is
"*unsafe-global*" safe-param is "(*safe-param*)) 

(thread-start! thread) 

(thread-sleep! 1) ;; make global safe for test 

(print "3main> before thread-join unsafe-global is "*unsafe-global*"
safe-param is "(*safe-param*)) 

(thread-join! thread) 

(print "5main> after thread-join unsafe-global is "*unsafe-global*"
safe-param is "(*safe-param* 

(main) 

;; actual stdout: 

;; 1main> before thread-start unsafe-global is #f safe-param is #f 

;; 2thread> unsafe-global is 42 safe-param is 42 

;; 3main> before thread-join unsafe-global is 42 safe-param is #f 

;; 4thread> just before exit unsafe-global is 42 safe-param is 42 

;; 5main> after thread-join unsafe-global is 42 safe-param is #f 

;; expected stdout for line 5: 

;; 5main> after thread-join unsafe-global is 42 safe-param is 42 

;; Why does the mutation of a simple global in a thread become visible
to the main thread, but the mutation of global parameter does not? 

;; What is the right way to achieve an thread-safe parameter? 

Thank you! 

   -Brandon___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users