@@ -91,8 +91,6 @@ <h1>Intro</h1>
91
91
program but are scheduled cooperatively by libevent. This differs from
92
92
< a href ="http://docs.python.org/library/subprocess.html "> subprocceses</ a >
93
93
in which new processes are spawned by the OS.
94
-
95
- At the time of writing, greenlets are only working in Python 2.x .
96
94
</ p >
97
95
98
96
</ header >
@@ -210,7 +208,6 @@ <h3>Synchronous & Asynchronous Execution</h3>
210
208
requests given the load on the remote server.</ p >
211
209
212
210
< pre > < code class ="python "> import gevent
213
- from gevent import Greenlet
214
211
import urllib2
215
212
import simplejson as json
216
213
@@ -241,6 +238,160 @@ <h3>Synchronous & Asynchronous Execution</h3>
241
238
</ code >
242
239
</ pre >
243
240
241
+ < h3 > Race Conditions</ h3 >
242
+
243
+ < p > The perennial problem involved with concurrency is known as a
244
+ < b > race condition</ b > . Simply put is when two concurrent threads
245
+ / processes depend on some shared resource but also attempt to
246
+ modify this value. This results in resources whose values become
247
+ time-dependent on the execution order. This is a problem, and in
248
+ general one should very much try to avoid race conditions since
249
+ they result program behavior which is globally non-deterministic.</ p >
250
+
251
+ < p > One approach to avoiding race conditions is to simply not
252
+ have any global < b > state</ b > shared between threads. To
253
+ communicate threads instead pass stateless messages between each
254
+ other.</ p >
255
+
256
+ </ section >
257
+
258
+ < section >
259
+ < h3 > Spawning threads</ h3 >
260
+
261
+ gevent provides a few wrappers around Greenlet initialization.
262
+ Some of the most common patterns are:
263
+
264
+ < pre >
265
+ < code class ="python "> import gevent
266
+ from gevent import Greenlet
267
+
268
+ def foo(message, n):
269
+ """
270
+ Each thread will be passed the message, and n arguments
271
+ in its initialization.
272
+ """
273
+ print 'I live!'
274
+ gevent.sleep(3)
275
+
276
+ # Initialize a new Greenlet instance running the named function
277
+ # foo
278
+ thread1 = Greenlet.spawn(foo, "Hello", 1)
279
+ thread1.start()
280
+
281
+ # Wrapper for creating and runing a new Greenlet from the named
282
+ # function foo, with the passd arguments
283
+ thread2 = gevent.spawn(foo, "I live!", 2)
284
+
285
+ # Lambda expressions
286
+ thread3 = gevent.spawn(lambda x: (x+1), 2)
287
+
288
+ threads = [thread1, thread2, thread3]
289
+
290
+ # Block until all threads complete.
291
+ gevent.joinall(threads)
292
+
293
+ </ code >
294
+ </ pre >
295
+ </ section >
296
+
297
+ <!-- ================================================= -->
298
+
299
+ < section >
300
+ < h3 > Greenlet State</ h3 >
301
+
302
+ < p > Like any other segement of code Greenlets can fail in various
303
+ ways. A greenlet may fail throw an exception, fail to halt or
304
+ consume too many system resources.</ p >
305
+
306
+ < p > The internal state of a greenlet is generally a time-depenent
307
+ parameter. There are a number of flags on greenlets which let
308
+ you monitor the state of the thread</ p >
309
+
310
+ < ul >
311
+ < li > < code > started</ code > -- Boolean, indicates whether the Greenlet has been started. </ li >
312
+ < li > < code > ready()</ code > -- Boolean, indicates whether the Greenlet has halted</ li >
313
+ < li > < code > successful()</ code > -- Boolean, indicates whether the Greenlet has halted and not thrown an exception</ li >
314
+ < li > < code > value</ code > -- arbitrary, the value returned by the Greenlet</ li >
315
+ < li > < code > exception</ code > -- exception, uncaught exception instance thrown inside the greenlet</ li >
316
+ </ ul >
317
+
318
+ < p >
319
+ Greenlets that fail to yield when the main program receives a
320
+ SIGQUIT may hold the program's execution longer than expected.
321
+ This results in so called "zombie processes" which need to be
322
+ killed from outside of the Python interpreter.
323
+ </ p >
324
+
325
+ A common pattern is to listen SIGQUIT events on the main program
326
+ and to invoke < code > gevent.killall</ code > before exit.
327
+
328
+ < pre >
329
+ < code class ="python "> import gevent
330
+
331
+ def run_forever():
332
+ while True:
333
+ pass
334
+
335
+ def main():
336
+ thread = gevent.spawn(run_forever)
337
+ gevent.joinall([thread])
338
+
339
+ if __name__ == '__main__':
340
+ try:
341
+ main()
342
+ except KeyboardInterrupt:
343
+ gevent.killall()
344
+ </ code >
345
+ </ pre >
346
+
347
+ < section >
348
+ < h3 > Timeouts</ h3 >
349
+
350
+ </ section >
351
+
352
+ <!-- ================================================= -->
353
+
354
+ <!-- ================================================= -->
355
+
356
+ < section >
357
+ < h2 > Data Structures</ h2 >
358
+ < h3 > Data Structures</ h3 >
359
+
360
+ Events are a form of asynchronous communication between
361
+ Greenlets.
362
+
363
+ < code class ="python "> import gevent
364
+ </ code >
365
+
366
+ </ section >
367
+
368
+ <!-- ================================================= -->
369
+
370
+ < section >
371
+ < h3 > Queues</ h3 >
372
+
373
+ < code class ="python ">
374
+ </ code >
375
+
376
+ </ section >
377
+
378
+ <!-- ================================================= -->
379
+
380
+ < section >
381
+ < h3 > Locks and Semaphores</ h3 >
382
+
383
+ < code class ="python ">
384
+ </ code >
385
+
386
+ </ section >
387
+
388
+ <!-- ================================================= -->
389
+
390
+ < section >
391
+ < h3 > Actor Model</ h3 >
392
+ The actor model is a higher level concurrency model popularized
393
+ by the language Erlang. In short the model revolves around
394
+ communication between a series
244
395
</ section >
245
396
246
397
< section id ="greenlets ">
@@ -279,6 +430,17 @@ <h3>Holding Side Effects</h3>
279
430
</ header >
280
431
</ section >
281
432
433
+ < section >
434
+ < h3 > WSGI Servers</ h3 >
435
+ </ section >
436
+
437
+ < section >
438
+ < h3 > Long Polling</ h3 >
439
+ </ section >
440
+
441
+ < section >
442
+ < h3 > Real world Example: Chat Server</ h3 >
443
+ </ section >
282
444
283
445
< h3 > License</ h3 >
284
446
0 commit comments