我有一个不可变的数据结构,它是一个在多个线程之间共享的功能性哈希图(参见fash.scm)。
想象一个线程想要将全局 hashmap 更改为新版本。我需要锁来更改值吗?如果是这种情况,我认为我还需要锁定值才能读取它,不是吗?
在我看来,这归结为在 Scheme 中设置值是否是原子操作。根据this answer for C language,您必须为指针的读写访问获取锁。
如果重要的话,我使用的是 guile 2.2.3 和 bigloo 4.3。
我有一个不可变的数据结构,它是一个在多个线程之间共享的功能性哈希图(参见fash.scm)。
想象一个线程想要将全局 hashmap 更改为新版本。我需要锁来更改值吗?如果是这种情况,我认为我还需要锁定值才能读取它,不是吗?
在我看来,这归结为在 Scheme 中设置值是否是原子操作。根据this answer for C language,您必须为指针的读写访问获取锁。
如果重要的话,我使用的是 guile 2.2.3 和 bigloo 4.3。
这一切都取决于你想做什么。一般来说,如果可以保证读取该值(例如总是一个数字),那么在读取该值时不锁定就可以了。例如,
(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 是如何实现的,但是只要条目没有更新为意外值,我认为不锁定是可以的。