hub && loop

event loop, hub 是一个单例的 greenlet, 用来调度 greenlet,每个 greenlet 都有一个 parent greenlet, loop server 在 hub里循环。hub = get_hub(); loop = hub.loop;



def patch_item(module, attr, newitem):
    NONE = object()
    olditem = getattr(module, attr, NONE)
    if olditem is not NONE:
        saved.setdefault(module.__name__, {}).setdefault(attr, olditem)
    setattr(module, attr, newitem)

def patch_module(name, items=None):
    gevent_module = getattr(__import__('gevent.' + name), name)
    module_name = getattr(gevent_module, '__target__', name)
    module = __import__(module_name)
    if items is None:
        items = getattr(gevent_module, '__implements__', None)
        if items is None:
            raise AttributeError('%r does not have __implements__' % gevent_module)
    for attr in items:
        patch_item(module, attr, getattr(gevent_module, attr))

以上是 gevent 的 patch module 的过程。现在简化一下,方便理解:

# 当前目录有:
def test():
    print "test in current module"
def test():
    print "test in modules"
def patch_module(name):
    my_module = getattr(__import__('modules.' + name), name)#modules.f1
    module_name = getattr(my_module, '__target__', name)#f1
    module = __import__(module_name) #module f1 in current
    items = dir(my_module)
    for attr in items:
        setattr(module, attr, getattr(my_module, attr))

import f1

using import can be that it returns the imported module and doesn’t add anything to the namespace; you can import with it without having then to delete the new name if you didn’t want that new name; using import somename will add somename to your namespace, but import(‘somename’) instead returns the imported module, which you can then ignore.


patch 了以下方法:

get_ident: 更改为获取当前协程的地址 id(greenlet.getcurrent())


def start_new_thread(function, args=(), kwargs={}):
    greenlet = Greenlet.spawn(function, *args, **kwargs)
    return get_ident(greenlet)