官术网_书友最值得收藏!

Greenlet and Gevent

The general principle of asynchronous programming is that the process deals with several concurrent execution contexts to simulate parallelism.

Asynchronous applications use an event loop that pauses and resumes execution contexts when an event is triggered--only one context is active, and they take turns. Explicit instruction in the code will tell the event loop that this is where it can pause the execution.

When that occurs, the process will look for some other pending work to resume. Eventually, the process will come back to your function and continue it where it stopped. Moving from an execution context to another is called switching.

The Greenlet project (https://github.com/python-greenlet/greenlet) is a package based on the Stackless project, a particular CPython implementation, and provides greenlets.

Greenlets are pseudo-threads that are very cheap to instantiate, unlike real threads, and that can be used to call Python functions. Within those functions, you can switch, and give back the control to another function. The switching is done with an event loop, and allows you to write an asynchronous application using a thread-like interface paradigm.

Here's an example from the Greenlet documentation:

    from greenlet import greenlet
def test1(x, y):
z = gr2.switch(x+y)
print(z)

def test2(u):
print (u)
gr1.switch(42)

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch("hello", " world")

The two greenlets in the preceding example explicitly switch from one to the other.

For building microservices based on the WSGI standard, if the underlying code uses greenlets, we could accept several concurrent requests, and just switch from one to another when we know a call is going to block the request--like I/O requests.

However, switching from one greenlet to another has to be done explicitly, and the resulting code can quickly become messy and hard to understand. That's where Gevent can become very useful.

The Gevent project (http://www.gevent.org/) is built on top of Greenlet, and offers an implicit and automatic way of switching between greenlets, among many other things.

It provides a cooperative version of the socket module, which uses greenlets to automatically pause and resume the execution when some data is made available in the socket. There's even a monkey patch feature, which automatically replaces the standard library socket with Gevent's version. That makes your standard synchronous code magically asynchronous every time it uses sockets--with just one extra line:

    from gevent import monkey; monkey.patch_all() 

def application(environ, start_response):
headers = [('Content-type', 'application/json')]
start_response('200 OK', headers)
# ...do something with sockets here...
return result

This implicit magic comes at a price though. For Gevent to work well, all the underlying code needs to be compatible with the patching that Gevent does. Some packages from the community will continue to block or even have unexpected results because of this--in particular, if they use C extensions, and bypass some of the features of the standard library Gevent patched.

But it works well for most cases. Projects that play well with Gevent are dubbed green, and when a library is not functioning well, and the community asks its authors to make it green, it usually happens.

That's what was used to scale the Firefox Sync service at Mozilla, for instance.

主站蜘蛛池模板: 北川| 威宁| 昌都县| 卓资县| 林州市| 邵东县| 赣榆县| 庆安县| 高清| 兴仁县| 颍上县| 河曲县| 清水县| 德安县| 徐州市| 镇安县| 凤阳县| 旬阳县| 启东市| 丰城市| 乐至县| 五寨县| 根河市| 含山县| 莱西市| 博野县| 龙海市| 河南省| 桂林市| 海南省| 凯里市| 龙门县| 通城县| 泌阳县| 章丘市| 阜平县| 新疆| 鲁甸县| 环江| 塘沽区| 南城县|