# gevent/greenlet.py
class Greenlet(greenlet):
    def __init__(self, run=None, *args, **kwargs):
        _greenlet__init__(self, None, get_hub()) # 指定hup为parent
        self._run = run # Greenlet.switch 切换会调用run函数
    @classmethod
    def spawn(cls, *args, **kwargs):
        g = cls(*args, **kwargs)
        g.start()
        return g
    def start(self):
        if self._start_event is None:
            self._start_event = self.parent.loop.run_callback(self.switch) # 注册swtich到loop
    def run(self):
        self._run(*self.args, **self.kwargs)
# gevent/hup.py
class Hub(WaitOperationsGreenlet):
    def run(self): # Hup.switch 切换会调用run函数
        while 1:
            try:
                self.loop.run() # 事件循环run
            finally:
                loop.error_handler = None # break the refcount cycle

import gevent

def test1():
    print('进入test1')
    gevent.sleep(0)
    print('切换test1')

def test2():
    print('进入test2')
    gevent.sleep(0)
    print('切换test2')

gevent.joinall([
    gevent.spawn(test1),
    gevent.spawn(test2),
]) 

进入test1
进入test2
切换test1
切换test2
gevent/monkey.py
@_ignores_DoNotPatch
def patch_socket(dns=True, aggressive=True):
  if dns:
        items = socket.__implements__ 
 else:
        items = set(socket.__implements__) - set(socket.__dns__) 
 _patch_module('socket', items=items) # patched socket

gevent/_socket2.py
class socket(object):
 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
        self._sock.setblocking(0) # 设置非阻塞的 socket
        fileno = self._sock.fileno()
        self.hub = get_hub()
        io = self.hub.loop.io
        self._read_event = io(fileno, 1)
        self._write_event = io(fileno, 2)
# gevent/monkey.py
def patch_all(socket=True, dns=True, time=True, select=True, thread=True,os=True,ssl=True,
   httplib=False, # Deprecated, to be removed.
   subprocess=True, sys=False, aggressive=True, Event=True,
   builtins=True, signal=True,
   queue=True,
   **kwargs):
   # order is important
    if os:
        patch_os()
    if time:
        patch_time()
    if thread:
        patch_thread(Event=Event, _warnings=_warnings)
    if sys:
        patch_sys()
    if socket:
        patch_socket(dns=dns, aggressive=aggressive)
    if select:
        patch_select(aggressive=aggressive)
    if ssl:
        patch_ssl(_warnings=_warnings, _first_time=first_time)
    if httplib:
        raise ValueError('gevent.httplib is no longer provided, httplib must be False')
    if subprocess:
        patch_subprocess()
    if builtins:
        patch_builtins()
    if signal:
        patch_signal()
    if queue:
        patch_queue()
   
# gevent/monkey.py
@_ignores_DoNotPatch
def patch_time():
 _patch_module('time') # 使用gevent.time模块
# gevent/time.py
 from gevent.hub import sleep
 sleep = sleep # gevent sleep 阻塞当前协程

qiumxfjg
1 声望0 粉丝