eventlet是否为线程模块执行monkey_patch?

时间:2015-09-08 07:50:17

标签: python eventlet green-threads

这里的文档http://eventlet.net/doc/patching.htm说"如果没有指定参数,那么所有内容都会被修补。"和"线程,修补线程,线程和队列"。

但是通过一个简单的测试:

#!/bin/env python

import threading

import eventlet
eventlet.monkey_patch()

if __name__ == '__main__':
    patched = eventlet.patcher.is_monkey_patched(threading)
    print('patched : %s' % patched)

结果是:

patched : False

似乎线程根本没有打补丁。 文档错了吗?

1 个答案:

答案 0 :(得分:1)

我发现文档是对的。问题是关于is_monkey_patched(),它无法检测某些情况,如'threading,Queue'模块。看看这个函数的src,行为很容易理解。

    if on['thread'] and not already_patched.get('thread'):
        modules_to_patch += _green_thread_modules()
        already_patched['thread'] = True
def is_monkey_patched(module):
    """Returns True if the given module is monkeypatched currently, False if
    not.  *module* can be either the module itself or its name.

    Based entirely off the name of the module, so if you import a
    module some other way than with the import keyword (including
    import_patched), this might not be correct about that particular
    module."""
    return module in already_patched or \
        getattr(module, '__name__', None) in already_patched
    for name, mod in modules_to_patch:
        orig_mod = sys.modules.get(name)
        if orig_mod is None:
            orig_mod = __import__(name)
        for attr_name in mod.__patched__:
            patched_attr = getattr(mod, attr_name, None)
            if patched_attr is not None:
                setattr(orig_mod, attr_name, patched_attr)

因为补丁操作是这样实现的:

 >>>import threading
 >>>eventlet.monkey_patch()
 >>>threading.current_thread.__module__
 >>>'eventlet.green.threading' 

我们可以使用以下方法检查是否修补了类似线程/队列的模块:

(BOOL)checkIfNeedsUpdate {
    BOOL needsUpdate = NO;
    NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];

    NSString* appID = infoDictionary[@"CFBundleIdentifier"];
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/ph/lookup?bundleId=%@", appID]];
    NSData* data = [NSData dataWithContentsOfURL:url];
    NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

    if([lookup[@"resultCount"] integerValue] == 1) {
        NSString* appStoreVersion = lookup[@"results"][0][@"version"];
        NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
        if(![appStoreVersion isEqualToString:currentVersion]) {
            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"logined"];
            [[NSUserDefaults standardUserDefaults] synchronize];

            needsUpdate = YES;
        }
    }

    return needsUpdate;
}