Gevent和猴子补丁

定义

在2018年看Flutent python时了解到猴子补丁,知道咋回事,但是现在通过代码更深刻认识猴子补丁。
猴子补丁:在运行时修改类或模块,而不改动源码。

例子1 没有用猴子补丁

import gevent
from gevent import socket
# from gevent import monkey; monkey.patch_socket()

urls = ['www.google.com', 'www.163.com', 'www.baidu.com']

def func(url):
    import requests
    result = requests.get('http://' + url)
    return result


jobs = [gevent.spawn(func, url) for url in urls]
gevent.joinall(jobs, timeout=2)

print([job.value for job in jobs])

结果:
线程一直阻塞,没有输出结果到终端。

例子2 用了猴子补丁

import gevent
from gevent import socket
from gevent import monkey; monkey.patch_socket()

urls = ['www.google.com', 'www.163.com', 'www.baidu.com']

def func(url):
    import requests
    result = requests.get('http://' + url)
    return result


jobs = [gevent.spawn(func, url) for url in urls]
gevent.joinall(jobs, timeout=2)

print([job.value for job in jobs])

结果显示并没有阻塞:

本质

  1. requests是个同步库,所以会发生阻塞。
  2. requests基于urllib3, urllib3基于socket,例子2用gevent的非阻塞socket(由greenlet运行的socket)代替urllib3的socket,所以不阻塞了。
  3. The primary pattern used in gevent is the Greenlet, a lightweight coroutine provided to Python as a C extension module

    参考

  4. https://en.wikipedia.org/wiki/Monkey_patch
  5. http://www.gevent.org/intro.html#monkey-patching

猜你喜欢

转载自www.cnblogs.com/allen2333/p/11346670.html