1Condition(3)                     OCaml library                    Condition(3)
2
3
4

NAME

6       Condition - Condition variables.
7

Module

9       Module   Condition
10

Documentation

12       Module Condition
13        : sig end
14
15
16       Condition variables.
17
18       Condition  variables  are  useful when several threads wish to access a
19       shared data structure that is protected by a mutex (a mutual  exclusion
20       lock).
21
22       A  condition variable is a communication channel. On the receiver side,
23       one or more threads can indicate that they wish to wait for  a  certain
24       property  to  become true. On the sender side, a thread can signal that
25       this property has become true, causing one (or more) waiting threads to
26       be woken up.
27
28       For  instance,  in  the  implementation of a queue data structure, if a
29       thread that wishes to extract an element finds that the queue  is  cur‐
30       rently  empty, then this thread waits for the queue to become nonempty.
31       A thread that inserts an element into the queue signals that the  queue
32       has  become  nonempty.  A  condition variable is used for this purpose.
33       This communication channel conveys the information  that  the  property
34       "the  queue  is nonempty" is true, or more accurately, may be true. (We
35       explain below why the receiver of a signal cannot be certain  that  the
36       property holds.)
37
38       To  continue  the  example  of the queue, assuming that the queue has a
39       fixed maximum capacity, then a thread that wishes to insert an  element
40       may  find  that  the queue is full. Then, this thread must wait for the
41       queue to become not full, and a thread that extracts an element of  the
42       queue  signals  that  the  queue has become not full. Another condition
43       variable is used for this purpose.
44
45       In short, a condition variable c is used to convey the information that
46       a  certain  property  P about a shared data structure D, protected by a
47       mutex m , may be true.
48
49       Condition variables provide an efficient alternative  to  busy-waiting.
50       When one wishes to wait for the property P to be true, instead of writ‐
51       ing a busy-waiting loop:
52            Mutex.lock m;
53            while not P do
54              Mutex.unlock m; Mutex.lock m
55            done;
56            <update the data structure>;
57            Mutex.unlock m
58
59       one uses Condition.wait in the body of the loop, as follows:
60            Mutex.lock m;
61            while not P do
62              Condition.wait c m
63            done;
64            <update the data structure>;
65            Mutex.unlock m
66
67       The busy-waiting loop is inefficient because the  waiting  thread  con‐
68       sumes  processing time and creates contention of the mutex m .  Calling
69       Condition.wait allows the waiting thread to be suspended,  so  it  does
70       not consume any computing resources while waiting.
71
72       With  a condition variable c , exactly one mutex m is associated.  This
73       association is implicit: the mutex m is not explicitly passed as an ar‐
74       gument  to  Condition.create  . It is up to the programmer to know, for
75       each condition variable c , which is the associated mutex m .
76
77       With a mutex m , several condition variables can be associated.  In the
78       example  of  the bounded queue, one condition variable is used to indi‐
79       cate that the queue is nonempty, and another condition variable is used
80       to indicate that the queue is not full.
81
82       With  a condition variable c , exactly one logical property P should be
83       associated. Examples of such properties include "the queue is nonempty"
84       and "the queue is not full".  It is up to the programmer to keep track,
85       for each condition variable, of the corresponding property P.  A signal
86       is  sent on the condition variable c as an indication that the property
87       P is true, or may be true.  On the receiving  end,  however,  a  thread
88       that  is  woken up cannot assume that P is true; after a call to Condi‐
89       tion.wait terminates, one must  explicitly  test  whether  P  is  true.
90       There  are several reasons why this is so.  One reason is that, between
91       the moment when the signal is sent and the moment when a waiting thread
92       receives  the  signal and is scheduled, the property P may be falsified
93       by some other thread that is able to acquire the mutex m and alter  the
94       data structure D.  Another reason is that spurious wakeups may occur: a
95       waiting thread can be woken up even if no signal was sent.
96
97       Here is a complete example, where a mutex  protects  a  sequential  un‐
98       bounded  queue,  and  where a condition variable is used to signal that
99       the queue is nonempty.
100            type 'a safe_queue =
101              { queue : 'a Queue.t; mutex : Mutex.t; nonempty : Condition.t }
102
103            let create () =
104              { queue = Queue.create(); mutex = Mutex.create();
105                nonempty = Condition.create() }
106
107            let add v q =
108              Mutex.lock q.mutex;
109              let was_empty = Queue.is_empty q.queue in
110              Queue.add v q.queue;
111              if was_empty then Condition.broadcast q.nonempty;
112              Mutex.unlock q.mutex
113
114            let take q =
115              Mutex.lock q.mutex;
116              while Queue.is_empty q.queue do Condition.wait q.nonempty q.mutex done;
117              let v = Queue.take q.queue in (* cannot fail since queue is nonempty *)
118              Mutex.unlock q.mutex;
119              v
120
121       Because the call to Condition.broadcast takes place inside the critical
122       section,  the  following property holds whenever the mutex is unlocked:
123       if the queue is nonempty, then no  thread  is  waiting,  or,  in  other
124       words,  if  some thread is waiting, then the queue must be empty.  This
125       is a desirable property: if a thread that attempts to  execute  a  take
126       operation  could  remain  suspended  even though the queue is nonempty,
127       that would be a problematic situation, known as a deadlock.
128
129
130
131
132
133       type t
134
135
136       The type of condition variables.
137
138
139
140       val create : unit -> t
141
142
143       create() creates and returns a new condition variable.  This  condition
144       variable should be associated (in the programmer's mind) with a certain
145       mutex m and with a certain property P of the  data  structure  that  is
146       protected by the mutex m .
147
148
149
150       val wait : t -> Mutex.t -> unit
151
152       The  call  wait c m is permitted only if m is the mutex associated with
153       the condition variable c , and only if m  is  currently  locked.   This
154       call  atomically unlocks the mutex m and suspends the current thread on
155       the condition variable c . This thread can later be woken up after  the
156       condition  variable  c has been signaled via Condition.signal or Condi‐
157       tion.broadcast ; however, it can also be woken up for  no  reason.  The
158       mutex m is locked again before wait returns. One cannot assume that the
159       property P associated with the condition variable c holds when wait re‐
160       turns; one must explicitly test whether P holds after calling wait .
161
162
163
164       val signal : t -> unit
165
166
167       signal  c wakes up one of the threads waiting on the condition variable
168       c , if there is one. If there is none, this call has no effect.
169
170       It is recommended to call signal c inside a critical section, that  is,
171       while the mutex m associated with c is locked.
172
173
174
175       val broadcast : t -> unit
176
177
178       broadcast  c wakes up all threads waiting on the condition variable c .
179       If there are none, this call has no effect.
180
181       It is recommended to call broadcast c inside a critical  section,  that
182       is, while the mutex m associated with c is locked.
183
184
185
186
187
188OCamldoc                          2023-07-20                      Condition(3)
Impressum