0

As far as I know, OCaml does offer concurrency but not parallelism (Why OCaml's threading is considered as `not enough`?)

Then why does OCaml still offer Mutex module and provide lock?

If no two threads can run simultaneously, then why we still need lock?

Community
  • 1
  • 1
Jackson Tale
  • 25,428
  • 34
  • 149
  • 271

2 Answers2

3

In general there are critical regions in code modifying data shared between threads that leave that data in an inconsistent state. This is precisely the same problem as when there are simultaneously executing processes. As @nlucaroni points out, a context switch in the middle of a critical region should not allow another thread into the same critical region. For example:

(* f should count the number of times it's called *)
let f = 
  let x = ref 0 in
  fun () -> 
    x := !x + 1;
    !x

A context switch after the lookup of x but before the store can clearly result in a miscount. This is fixed with a mutex.

(* f should count the number of times it's called *)
let f = 
  let x = ref 5 in
  let m = Mutex.create () in
  fun () -> 
    Mutex.lock m;
    x := !x + 1;
    let ret = !x in
    Mutex.unlock m;
    ret

will fix this.

seanmcl
  • 9,740
  • 3
  • 39
  • 45
  • when will this context switch happen? – Jackson Tale Apr 14 '14 at 19:30
  • The thread scheduler can switch contexts as it pleases. I haven't studied the implementation myself. I beleive that the file is otherlibs/threads/scheduler.c in the implementation. – seanmcl Apr 14 '14 at 19:34
  • It is one of the fundamentals in concurrency/multiprogramming or what term you may use that a context switch can occur at any point between two machine instructions (timer, for example). – Str. Apr 14 '14 at 22:02
  • There will be no OCaml context switch in `x := !x + 1` - hence no problem in practice here, the corruption will be visible with more complex operations or data structures. The answer in general is still true of course. – ygrek Apr 15 '14 at 09:56
  • @ygrek. How do you know there won't be a context switch there? – seanmcl Apr 15 '14 at 13:21
  • I believe OCaml context switches only on allocation. So a long for loop incrementing the same integer will starve the other threads for example. – rgrinberg Apr 15 '14 at 15:49
  • 2
    Look at the generated assembly and remember of GC lock. OCaml threads may switch only at the points where GC lock is released, the most common cases are explicit unlocking in C bindings or opportunistic unlocking at allocation sites. – ygrek Apr 15 '14 at 15:49
0

Because mutex is a concurrency primitive, not specific for parallelism. It is used to make execution of piece of code atomic from the point of view of other concurrent entities. It is used to organize exclusive access to specific portion of data while executing specific piece of code (e.g. to ensure that only single concurrent thread of execution is modifying data breaking the invariants in process but restoring those invariants before releasing the mutex so that other concurrent threads of execution will see consistent data when they get access to it).

ygrek
  • 6,656
  • 22
  • 29
  • My point is if not for parallelism and no two threads can run in parallel (real simultaneously), then why lock? – Jackson Tale Apr 15 '14 at 10:23
  • Because you may want to have an exclusive access to some piece of data for some period of time. – ygrek Apr 15 '14 at 15:47