0
# Synchronization
1
2
Thread-safe synchronization objects adapted for cooperative greenlet concurrency. These primitives enable coordination between greenlets while maintaining the cooperative nature of gevent's event loop.
3
4
## Capabilities
5
6
### Events
7
8
Binary state signaling between greenlets.
9
10
```python { .api }
11
class Event:
12
"""
13
Event object for signaling between greenlets.
14
"""
15
16
def set(self):
17
"""
18
Set the event, notifying all waiting greenlets.
19
20
Returns:
21
None
22
"""
23
24
def clear(self):
25
"""
26
Clear the event.
27
28
Returns:
29
None
30
"""
31
32
def wait(self, timeout=None) -> bool:
33
"""
34
Wait for the event to be set.
35
36
Parameters:
37
- timeout: float, maximum time to wait in seconds
38
39
Returns:
40
bool, True if event was set, False if timeout occurred
41
"""
42
43
def is_set(self) -> bool:
44
"""
45
Check if the event is set.
46
47
Returns:
48
bool, True if event is set
49
"""
50
51
def isSet(self) -> bool:
52
"""
53
Alias for is_set() for threading compatibility.
54
55
Returns:
56
bool, True if event is set
57
"""
58
```
59
60
### Async Results
61
62
Container for results that may not be available immediately.
63
64
```python { .api }
65
class AsyncResult:
66
"""
67
Container for a result that may not be available yet.
68
"""
69
70
def set(self, value=None):
71
"""
72
Set the result value.
73
74
Parameters:
75
- value: any, the result value
76
77
Returns:
78
None
79
"""
80
81
def set_exception(self, exception):
82
"""
83
Set an exception as the result.
84
85
Parameters:
86
- exception: Exception object
87
88
Returns:
89
None
90
"""
91
92
def get(self, block=True, timeout=None):
93
"""
94
Get the result, blocking if necessary.
95
96
Parameters:
97
- block: bool, whether to block if result not ready
98
- timeout: float, maximum time to wait in seconds
99
100
Returns:
101
The result value
102
103
Raises:
104
The stored exception if one was set
105
"""
106
107
def ready(self) -> bool:
108
"""
109
Check if result is available.
110
111
Returns:
112
bool, True if result is ready
113
"""
114
115
def successful(self) -> bool:
116
"""
117
Check if result completed successfully.
118
119
Returns:
120
bool, True if completed without exception
121
"""
122
123
def wait(self, timeout=None) -> bool:
124
"""
125
Wait for result to be available.
126
127
Parameters:
128
- timeout: float, maximum time to wait in seconds
129
130
Returns:
131
bool, True if result became available
132
"""
133
```
134
135
### Semaphores
136
137
Counting synchronization primitive to limit resource access.
138
139
```python { .api }
140
class Semaphore:
141
"""
142
Semaphore for limiting concurrent access to resources.
143
"""
144
145
def __init__(self, value=1):
146
"""
147
Initialize semaphore with given value.
148
149
Parameters:
150
- value: int, initial semaphore count
151
"""
152
153
def acquire(self, blocking=True, timeout=None) -> bool:
154
"""
155
Acquire the semaphore.
156
157
Parameters:
158
- blocking: bool, whether to block if semaphore unavailable
159
- timeout: float, maximum time to wait in seconds
160
161
Returns:
162
bool, True if acquired successfully
163
"""
164
165
def release(self):
166
"""
167
Release the semaphore.
168
169
Returns:
170
None
171
"""
172
173
def wait(self, timeout=None) -> bool:
174
"""
175
Wait for semaphore to become available.
176
177
Parameters:
178
- timeout: float, maximum time to wait in seconds
179
180
Returns:
181
bool, True if semaphore became available
182
"""
183
184
class BoundedSemaphore(Semaphore):
185
"""
186
Semaphore with maximum value bounds to prevent over-release.
187
"""
188
189
class DummySemaphore:
190
"""
191
No-op semaphore for testing or disabled synchronization.
192
"""
193
```
194
195
### Locks
196
197
Mutual exclusion locks for protecting critical sections.
198
199
```python { .api }
200
class RLock:
201
"""
202
Reentrant lock that can be acquired multiple times by same greenlet.
203
"""
204
205
def acquire(self, blocking=True, timeout=None) -> bool:
206
"""
207
Acquire the lock.
208
209
Parameters:
210
- blocking: bool, whether to block if lock unavailable
211
- timeout: float, maximum time to wait in seconds
212
213
Returns:
214
bool, True if acquired successfully
215
"""
216
217
def release(self):
218
"""
219
Release the lock.
220
221
Returns:
222
None
223
"""
224
```
225
226
### Waiting and Watching
227
228
Primitives for waiting on multiple objects.
229
230
```python { .api }
231
def iwait(objects, timeout=None, count=None):
232
"""
233
Iteratively wait for objects to become ready.
234
235
Parameters:
236
- objects: iterable of objects to wait on
237
- timeout: float, maximum time to wait in seconds
238
- count: int, maximum number of objects to wait for
239
240
Yields:
241
Objects as they become ready
242
"""
243
244
def wait(objects, timeout=None, count=None) -> list:
245
"""
246
Wait for objects to become ready.
247
248
Parameters:
249
- objects: iterable of objects to wait on
250
- timeout: float, maximum time to wait in seconds
251
- count: int, maximum number of objects to wait for
252
253
Returns:
254
list of objects that became ready
255
"""
256
```
257
258
## Usage Examples
259
260
### Event Coordination
261
262
```python
263
import gevent
264
from gevent import event
265
266
# Create event
267
ready = event.Event()
268
269
def waiter(name):
270
print(f"{name} waiting for event")
271
ready.wait()
272
print(f"{name} proceeding")
273
274
def setter():
275
gevent.sleep(2)
276
print("Setting event")
277
ready.set()
278
279
# Start waiters and setter
280
gevent.joinall([
281
gevent.spawn(waiter, "Worker 1"),
282
gevent.spawn(waiter, "Worker 2"),
283
gevent.spawn(setter)
284
])
285
```
286
287
### Producer-Consumer with AsyncResult
288
289
```python
290
import gevent
291
from gevent import event
292
293
def producer(result):
294
# Simulate work
295
gevent.sleep(1)
296
result.set("Produced data")
297
298
def consumer(result):
299
data = result.get() # Blocks until available
300
print(f"Consumed: {data}")
301
302
result = event.AsyncResult()
303
gevent.joinall([
304
gevent.spawn(producer, result),
305
gevent.spawn(consumer, result)
306
])
307
```
308
309
### Resource Pool with Semaphore
310
311
```python
312
import gevent
313
from gevent import lock
314
315
# Limit to 3 concurrent workers
316
pool = lock.Semaphore(3)
317
318
def worker(name):
319
with pool: # Context manager support
320
print(f"{name} acquired resource")
321
gevent.sleep(1) # Simulate work
322
print(f"{name} releasing resource")
323
324
# Start more workers than pool size
325
workers = [gevent.spawn(worker, f"Worker {i}") for i in range(10)]
326
gevent.joinall(workers)
327
```