gunicorn Arbiter 源码解析
Arbiter(self).run()
def run()
self.init_signal()
self.LISTENERS = create_sockets(self.cfg, self.log)
self.manage_workers()
while True:
if no signal in SIG_QUEUE
self.sleep()
else:
handle_signal()
def spawn_worker(self):
self.worker_age += 1
worker = self.worker_class(self.worker_age, self.pid, self.LISTENERS,
self.app, self.timeout / 2.0,
self.cfg, self.log)
self.cfg.pre_fork(self, worker)
pid = os.fork()
if pid != 0:
self.WORKERS[pid] = worker
return pid # Process Child
worker_pid = os.getpid()
try:
util._setproctitle("worker [%s]" % self.proc_name)
self.log.info("Booting worker with pid: %s", worker_pid)
self.cfg.post_fork(self, worker)
worker.init_process()
sys.exit(0)
except SystemExit:
raise
except AppImportError as e:
self.log.debug("Exception while loading the application",
exc_info=True)
print("%s" % e, file=sys.stderr)
sys.stderr.flush()
sys.exit(self.APP_LOAD_ERROR)
except:
self.log.exception("Exception in worker process"),
if not worker.booted:
sys.exit(self.WORKER_BOOT_ERROR)
sys.exit(-1)
finally:
self.log.info("Worker exiting (pid: %s)", worker_pid)
try:
worker.tmp.close()
self.cfg.worker_exit(self, worker)
except:
self.log.warning("Exception during worker exit:\n%s",
traceback.format_exc())
Arbiter.spawn_worker

# prefork.py
import sys
import socket
import select
import os
import time def do_sub_process():
pid = os.fork()
if pid < 0:
print 'fork error'
sys.exit(-1)
elif pid > 0:
print 'fork sub process %d' % pid
return # must be child process
time.sleep(1)
print 'sub process will exit', os.getpid(), os.getppid()
sys.exit(0) def main():
sub_num = 2
for i in range(sub_num):
do_sub_process()
time.sleep(10)
print 'main process will exit', os.getpid() if __name__ == '__main__':
main()
def kill_worker(self, pid, sig):
"""\
Kill a worker :attr pid: int, worker pid
:attr sig: `signal.SIG*` value
"""
try:
os.kill(pid, sig)
except OSError as e:
if e.errno == errno.ESRCH:
try:
worker = self.WORKERS.pop(pid)
worker.tmp.close()
self.cfg.worker_exit(self, worker)
return
except (KeyError, OSError):
return
raise
def sleep(self):
"""\
Sleep until PIPE is readable or we timeout.
A readable PIPE means a signal occurred.
"""
ready = select.select([self.PIPE[0]], [], [], 1.0) # self.PIPE = os.pipe()
if not ready[0]:
return
while os.read(self.PIPE[0], 1):
pass
代码里面的注释写得非常清楚,要么PIPE可读立即返回,要么等待超时。管道可读是因为有信号发生。这里看看pipe函数
os.pipe()-
Create a pipe. Return a pair of file descriptors
(r,w)usable for reading and writing, respectively.
def wakeup(self):
"""
Wake up the arbiter by writing to the PIPE
"""
os.write(self.PIPE[1], b'.')
最后附上Arbiter的信号处理:
- QUIT, INT: Quick shutdown
- TERM: Graceful shutdown. Waits for workers to finish their current requests up to the graceful timeout.
- HUP: Reload the configuration, start the new worker processes with a new configuration and gracefully shutdown older workers. If the application is not preloaded (using the
--preloadoption), Gunicorn will also load the new version. - TTIN: Increment the number of processes by one
- TTOU: Decrement the number of processes by one
- USR1: Reopen the log files
- USR2: Upgrade the Gunicorn on the fly. A separate TERM signal should be used to kill the old process. This signal can also be used to use the new versions of pre-loaded applications.
- WINCH: Gracefully shutdown the worker processes when Gunicorn is daemonized.
gunicorn Arbiter 源码解析的更多相关文章
- gunicorn syncworker 源码解析
gunicorn支持不同的worker类型,同步或者异步,异步的话包括基于gevent.基于eventlet.基于Aiohttp(python版本需要大于3.3),也有多线程的版本.下面是gunico ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- jQuery2.x源码解析(构建篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...
- jQuery2.x源码解析(设计篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...
随机推荐
- C#编写的艺术字类方法
代码如下: using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing ...
- (转)Ubuntu 12.04 中安装和配置 Java JDK
http://www.cnblogs.com/bluestorm/archive/2012/05/10/2493592.html 先去 Oracle下载Linux下的JDK压缩包,我下载的是jdk-7 ...
- 自定义统一api返回json格式(app后台框架搭建三)
在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...
- 【Java入门提高篇】Day3 抽象类与接口的比较
抽象类跟接口都讲完了,现在来做一个比较. 其实说实话,没有多大的可比较性,它们是完全不同的两个东西,它们的抽象不在同一个层级上.但是为了让大家更好的理解,还是做一个比较吧,毕竟它们都很抽象(233). ...
- SSM框架下结合 log4j、slf4j打印日志
首先加入log4j和slf4j的jar包 <!-- 日志处理 <!-- slf4j日志包--> <dependency> <groupId>org.slf4j ...
- python学习笔记 函数
形式: def function(a,b,c=0,*args,**kw)#a,b必选参数,*args可变参数,**kw关键字参数 1.函数的返回值可以是多个参数.多个参数时,实际上返回的是一个tupl ...
- openFace 人脸识别框架测试
openface 人脸识别框架 但个人感觉精度还是很一般 openface的githup文档地址:http://cmusatyalab.github.io/openface/ openface的安 ...
- AutoMapper在asp.netcore中的使用
# AutoMapper在asp.netcore中的使用 automapper 是.net 项目中针对模型之间转换映射的一个很好用的工具,不仅提高了开发的效率还使代码更加简洁,当然也是开源的,htt ...
- [特斯拉组件]ios高性能PageController
本文来自于腾讯Bugly公众号(weixinBugly),作者:sparrowchen,未经作者同意,请勿转载,原文地址: http://mp.weixin.qq.com/s/hBgvPBP12IQ1 ...
- 【原创】python实现清理本地缓存垃圾
#coding=utf-8 import os import glob try: #利用glob模块定位需要清理垃圾的模糊路径 File_1 = glob.glob("C:\Windows\ ...