Skip to content

Commit c3dfa6b

Browse files
committed
More work.
1 parent 951205d commit c3dfa6b

File tree

1 file changed

+165
-3
lines changed

1 file changed

+165
-3
lines changed

index.html

Lines changed: 165 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ <h1>Intro</h1>
9191
program but are scheduled cooperatively by libevent. This differs from
9292
<a href="http://docs.python.org/library/subprocess.html">subprocceses</a>
9393
in which new processes are spawned by the OS.
94-
95-
At the time of writing, greenlets are only working in Python 2.x .
9694
</p>
9795

9896
</header>
@@ -210,7 +208,6 @@ <h3>Synchronous & Asynchronous Execution</h3>
210208
requests given the load on the remote server.</p>
211209

212210
<pre><code class="python">import gevent
213-
from gevent import Greenlet
214211
import urllib2
215212
import simplejson as json
216213

@@ -241,6 +238,160 @@ <h3>Synchronous & Asynchronous Execution</h3>
241238
</code>
242239
</pre>
243240

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
244395
</section>
245396

246397
<section id="greenlets">
@@ -279,6 +430,17 @@ <h3>Holding Side Effects</h3>
279430
</header>
280431
</section>
281432

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>
282444

283445
<h3>License</h3>
284446

0 commit comments

Comments
 (0)