
Worker

- worker抛异常,worker循环会捕获这个异常丢给主进程
-
主进程再去做退出

- worker调用system.exit()
-
主进程发现worker异常退出,也抛出Runtime error
Main

- 主进程sys.exit()
-
worker会存活一会,拉一些数据,然后发现主进程已经挂了,就会主动退出

- 用os.exit直接退出。
-
同样子进程也额外打印了一些数据。也自动退出了
-
不过这里在退出的时候resource_tracker打印了有一些leak的资源。
-
因为sys.exit()好像是会调用del,而os.exit不会,类似kill
Hang

- main中有一个watch dog,如果过长时间没有执行loop了,会打印一下所有线程的堆栈,看一下当前卡在哪里了。

- worker如果不读数据hang住的话,主进程会退出

faulthandler


通过faulthandler,给SIGUSR1注册。
外部可以通过kill -SIGUSR1 pid,来触发worker进程的堆栈打印。
从上面例子中可以看到是卡到了具体哪一行。
Signal handler

相当于是自己实现的faulthandler。打印的日志更加详细。
不过如果是GIL卡住的话可能搞不定,因为不是在c层面做的,而是py。
方法和上面的watch dog一样,dump_all_threads_stacktrace
Pyspy
需要sudo权限,可能对线上环境不太友好。

也可以看到具体的hang的位置,不依赖sighandler
文章评论