Python gevent 学习

前言

为了看一下goagent 的代码,需要先补一下gevent 的知识。所以在这里记录下来。

官方:http://www.gevent.org/intro.html

tutorial:http://sdiehl.github.io/gevent-tutorial/ 


介绍 

geventpython的一个并发框架,以微线程greenlet为核心 ,实质就是协程,资源占用少,效率高


示例

第一个例子:

#!/usr/bin/python 

import gevent

def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')


def bar():
    print('Explicit context to bar')
    gevent.sleep(0)
    print('Implicit context switch back to bar')

gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),])
输出如下:

ubuntu@yee :/tmp$ python g.py 
Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar


gevent 是通过yielding 来实现上下文切换的,在程序中切换 的方法就是使用 :gevent.sleep(0)来切换到不同的协程


例子二:

同步和异步的处理

#!/usr/bin/python
#-*- coding:utf8  -*- 


import gevent
import random

def task(pid):
    gevent.sleep(random.randint(0,2)*0.001)
    print('Task',pid,'done')


def synchronous():
    for i in range(1,10):
        task(i)


def asynchronous():
    threads = [gevent.spawn(task,i) for i in range(1,10)]
    gevent.joinall(threads)

print('Synchronous:')
synchronous()


print('Asynchronous:')
asynchronous()
输出结果 :
ubuntu@yee:/tmp$ python test.py 
Synchronous:
('Task', 1, 'done')
('Task', 2, 'done')
('Task', 3, 'done')
('Task', 4, 'done')
('Task', 5, 'done')
('Task', 6, 'done')
('Task', 7, 'done')
('Task', 8, 'done')
('Task', 9, 'done')
Asynchronous:
('Task', 6, 'done')
('Task', 7, 'done')
('Task', 8, 'done')
('Task', 2, 'done')
('Task', 5, 'done')
('Task', 1, 'done')
('Task', 4, 'done')
('Task', 9, 'done')
('Task', 3, 'done')
由gevent.joinall传入协程列表来初始化 greenlets,这个过程会block 当前程序,然后随机运行greenlets的列表协程。

在同步中,每个 task 都会sleep 2秒钟,整个队列下来需要花掉20秒钟。而对于异步来说,当其它task  sleep的时候,其它task可以马上得到运行,2秒钟之后,所有的队列都可以运行完毕 。

所以,异步的速度相对比于同步来说更快。而需要注意的是,异步的执行顺序是不可控的。

例子三:

#!/usr/bin/python 
#-*- coding:utf8  -*-

import gevent.monkey
gevent.monkey.patch_socket()

import gevent
import urllib2
import time

def fetch(pid):
    response = urllib2.urlopen('http://www.baidu.com')
    result = response.read()

    print result[:30]

def synchronous():
    start  = time.clock()

    for i in range(1,30):
        fetch(i)

    end = (time.clock()-start)
    print("synchronous time used:",end)

def asynchronous():
    start  = time.clock()

    threads = []
    for i in range(1,30):
        threads.append(gevent.spawn(fetch,i))

    gevent.joinall(threads)
    end = (time.clock()-start)
    print("asynchronous time used:",end)


print 'synchronous:'
synchronous()

print 'asynchronous:'
asynchronous()

运行的时候可以明显感觉到异步的速度更快。

=...= 原文中有有些英文比较难,就不继续了。以上学到的这些基础已经暂时够用。









你可能感兴趣的:(Python gevent 学习)