0

我有一个不可变的数据结构,它是一个在多个线程之间共享的功能性哈希图(参见fash.scm)。

想象一个线程想要将全局 hashmap 更改为新版本。我需要锁来更改值吗?如果是这种情况,我认为我还需要锁定值才能读取它,不是吗?

在我看来,这归结为在 Scheme 中设置值是否是原子操作。根据this answer for C language,您必须为指针的读写访问获取锁。

如果重要的话,我使用的是 guile 2.2.3 和 bigloo 4.3。

4

1 回答 1

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 是如何实现的,但是只要条目没有更新为意外值,我认为不锁定是可以的。

于 2018-02-12T22:15:05.753 回答