我有一个不可变的数据结构,它是一个在多个线程之间共享的函数式散列映射(参见fash.scm)。
想象一下,线程想要将全局hashmap更改为新版本。 我是否需要锁来更改值?如果是这种情况,我假设我还需要锁定值才能读取它,不是吗?
在我看来,归结为在Scheme中设置值是否是原子操作。根据{{3}},你必须 获取指针的读写访问锁。
如果重要的话我使用的是guile 2.2.3和bigloo 4.3。
答案 0 :(得分:1)
这一切都取决于你想做什么。通常,如果可以保证读取值(例如总是一个数字),则可以在读取值时不锁定。例如,
(import (rnrs) (srfi :18))
(define count 0)
(define t
(thread-start!
(make-thread
(lambda ()
(let loop ()
(display count) (newline)
(thread-sleep! 0.1)
(loop))))))
(do ((i 0 (+ i 1))) ((= i 10))
(set! count (+ count 1))
(thread-sleep! 0.1))
这是非常安全的阅读。但是,如果值是,例如长度为1的向量,那么您可能想要锁定其他线程是否可以将值更改为#f或长度为0的向量。例如:
(import (rnrs) (srfi :18))
(define count (vector 1))
(define t
(thread-start!
(make-thread
(lambda ()
(let loop ()
(display (vector-ref count 0)) (newline)
(thread-sleep! 0.1)
(loop))))))
(do ((i 0 (+ i 1))) ((= i 10))
(vector-set! count 0 (+ (vector-ref count 0) i))
(thread-sleep! 0.1))
(set! count #f) ;; if this happens, the you may want to lock on reader thread
我没有检查fash是如何实现的,但只要条目没有更新为意外值,我认为可以不锁定。