Do I need a lock to access an immutable datastructure in multithreading context?

76 views Asked by At

I have an immutable datastructure that is a functional hashmap (see fash.scm) that is shared among several threads.

Imagine a thread wants to change the global hashmap to a new version. Do I need a lock to change the value? If that's is the case, I assume I also need to lock the value to read it, isn't it?

It seems to me it boils down to whether setting a value in Scheme is an atomic operation or not. According to this answer for C language, you must acquire a lock for both read and write access of pointer.

If it matters I am using guile 2.2.3 and bigloo 4.3.

1

There are 1 answers

0
Takashi Kato On

It all depends on what you want to do. In general, if the value can be guaranteed to be read (e.g. always a number), then it's okay not to lock when the value is read. For example,

(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))

This is pretty much safe to read. However if the value is, say a vector of length 1, then you may want to lock if the other threads may change the value to #f or a vector of length 0. For example:

(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

I haven't check how fash is implemented, but as long as entries are not updated to unexpected values, I would think it's okay not to lock.