在看tornado和Nginx代码的时候都会看到在最初事件反应堆初始化的时候都会自初始化一个事件,创建一个管道pipe并绑定到事件队列中。
这样的好处是可以优雅的在父进程中向管道pipe[0]发送退出或者其他信号,子进程监听到pipe[1]有事件产生后采取相应的措施。
class Waker(interface.Waker): def __init__(self): r, w = os.pipe() _set_nonblocking(r) _set_nonblocking(w) set_close_exec(r) set_close_exec(w) self.reader = os.fdopen(r, "rb", 0) self.writer = os.fdopen(w, "wb", 0) def fileno(self): return self.reader.fileno() def write_fileno(self): return self.writer.fileno() def wake(self): try: self.writer.write(b"x") except IOError: pass def consume(self): try: while True: result = self.reader.read() if not result: break except IOError: pass def close(self): self.reader.close() self.writer.close()
以上是tornado中对管道的包装,其作用是创建管道,并将这个对象作为一个事件注册到反应堆中,用于子进程idle(由于没有事件加上一些信号被屏蔽,进程处于epoll系统调用中)
的时候唤醒子进程、