pythoneventletgreen-threads

Does eventlet do monkey_patch for threading module?


Docs here in http://eventlet.net/doc/patching.htm says "If no arguments are specified, everything is patched." and "thread, which patches thread, threading, and Queue".

But with a simple test:

#!/bin/env python

import threading

import eventlet
eventlet.monkey_patch()

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

The result is:

patched : False

It seems like threading is not patched at all. The doc is wrong?


Solution

  • I found the doc is right. The problem is about is_monkey_patched(), it can't detect some situation like 'threading, Queue' module. Take a look at the src of this function, the behaviour is easy to understand.

    def _green_thread_modules():
        from eventlet.green import Queue
        from eventlet.green import thread
        from eventlet.green import threading
        if six.PY2:
            return [('Queue', Queue), ('thread', thread), ('threading', threading)]
        if six.PY3:
            return [('queue', Queue), ('_thread', thread), ('threading', threading)]
    

        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
    

    And because the patch operation is implemented like this:

        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)
    

    We can check whether a module like threading/Queue is patched by using:

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