Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4469242
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Python/Ruby

2015-01-05 21:42:47

原文地址:http://effi2.me/blog/2014/07/06/greenlet/

Jul 6th, 2014

“greenlet”是一个小而独立的虚拟线程,下面是一个小例子来解释它的用法。

 from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch() 

最后一行代码跳转(switch)至test1,打印12,跳转到test2,打印56,跳回到test1,打印34;然后test1执行结束,gr1死亡。这个时候,执行会返回gr1.switch()调用的地方,程序结束。78永远不会打印出来,除非在最后一行加上gr2.switch()。

每一个greenlet都有一个父greenlet,在其被创建的过程中能指定父greenlet,或者使用current greenlet。当子greenlet死亡后,执行点会返回到其父greenlet里。

greenlets以trees的方式组织,main greenlet是所有的grennlets的根节点,由系统默认生成。

那上个例子做说明,main greenlet是gr1和gr2的父greenlet,当gr1死亡时,执行点跳回main greenlet,程序结束。

 from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

print 'main greenlet:', greenlet.getcurrent()
gr1 = greenlet(test1)
print 'g1.parent:', gr1.parent
gr2 = greenlet(test2)
print 'g2.parent:', gr2.parent
gr1.switch()  

这里得出一个小结论:main greenlet死亡,程序会结束

未捕捉的异常也会传递给父greenlet, 除了greenlet.GreenletExit。如果你想让某个greenlet死亡,可以抛出greenlet.GreenletExit异常。

当某一个greenlet的switch函数调用的时候,greenlets之间会发生跳转,此时执行点跳转到调用switch函数的greenlet中。当某个greenlet死亡的时候,此时执行点会跳转到其父greenlet中。greenlet之间的跳转可以向目标greenlet传递一个object或exception,这可以很方便地在greenlets之间传递数据。

 from greenlet import greenlet

def test1(x, y):
    z = gr2.switch(x+y)
    print z
    return z*2

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

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

执行点跳转到gr1时将”hello”, “ world”传递给test1, 跳转到gr2时将”hello world”传递给test2,跳回到gr1时将42传递给gr2.switch的返回值,gr1死亡后将返回的数据传递给main greenlet。

Methods and attributes of greenlets

g.switch(*args, **kwargs)

greenlets之间切换执行点

g.run

当greenlet开始启动时要执行的函数,greenlet启动以后,这个属性将不再存在

g.parent

greenlet的父greenlet,可写属性,但不允许创建死循环。

g.gr_frame

根greenlet

g.dead

如果greenlet死掉,返回True

bool(g)

死亡或未启动状态返回False

g.throw([typ, [val, [tb]]])

Switches execution to the greenlet g, but immediately raises the given exception in g. If no argument is provided, the exception defaults to greenlet.GreenletExit. The normal exception propagation rules apply, as described above. Note that calling this method is almost equivalent to the following:

 def raiser():
    raise typ, val, tb
g_raiser = greenlet(raiser, parent=g)
g_raiser.switch() 

except that this trick does not work for the greenlet.GreenletExit exception, which would not propagate from g_raiser to g.

参考文章: greenlet: Lightweight concurrent programming

 Jul 6th, 2014 greenletpython

阅读(943) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~