在多线程上下文中是否需要锁来访问不可变数据结构?

时间:2018-02-12 18:38:05

标签: multithreading scheme immutability guile bigloo

我有一个不可变的数据结构,它是一个在多个线程之间共享的函数式散列映射(参见fash.scm)。

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

在我看来,归结为在Scheme中设置值是否是原子操作。根据{{​​3}},你必须 获取指针的读写访问锁。

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

1 个答案:

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