Python3运行时查看线程信息

前一篇文章说了一下在是用Python2的情况下怎样查看运行时线程信息,今天查资料的时候发现,原来在Python3中引入了 faulthandler 模块,可以简化我们很多工作,甚至,如果不需要保持进程继续运行的情况下可以不用修改我们已有的代码。具体 faulthandler 模块的使用,可以参考:

faulthandler https://docs.python.org/3/library/faulthandler.html

先准备一个小程序,就是周期性的往命令行终端输出一下时间,如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import threading
import traceback
import signal
import tempfile
from datetime import datetime
import time


def test():
    while True:
        print(datetime.now())
        time.sleep(2)


if __name__ == "__main__":
    try:
        threading.Thread(target=test).start()

        while True:
            time.sleep(60)
    except KeyboardInterrupt:
        sys.exit(1)

要启用 dump thread 的功能,可以通过三种方式来打开:

  1. 使用 PYTHONFAULTHANDLER=true 环境变量
  2. 使用 python3 -q -X faulthandler 来起用
  3. 代码方式来启用

这里我们通过设置环境变量 “PYTHONFAULTHANDLER=true” 来启用,用下面方式运行程序:

$ PYTHONFAULTHANDLER=true ./test.py

然后在另开一个终端运行下面的命令

$ kill -SIGABRT `ps -ef | grep test.py | grep -v 'grep' | awk '{print $2}'`

此时我们可以在运行 test.py 的终端中看到如下线程信息:

Fatal Python error: Aborted

Thread 0x00007f8298430700 (most recent call first):
  File "./test3.py", line 16 in test
  File "/usr/lib64/python3.4/threading.py", line 859 in run
  File "/usr/lib64/python3.4/threading.py", line 911 in _bootstrap_inner
  File "/usr/lib64/python3.4/threading.py", line 879 in _bootstrap

Current thread 0x00007f82a2fcf740 (most recent call first):
  File "./test3.py", line 24 in <module>
Aborted (core dumped)

这里我们是通过发送 SIGABRT 信号来触发的,其实也可以使用 SIGSEGV, SIGFPE, SIGABRT, SIGBUS 和 SIGILL 信号来出发。

运行上面的程序,我们发现一个问题,一旦dump threads后,进程就退出了,而如果我们不想让进程退出,该怎么办呢,这就要用到前一篇文章中说提到的复写信号处理函数了。

看一下下面的代码,我们和前一篇博客中一样都是复写 “SIGQUIT” 信号处理函数,在接受到 SIGQUIT 信号后,输出线程信息到 /tmp 目录下,然后程序继续运行。

#!/usr/bin/env /usr/bin/python3.4
# -*- coding: utf-8 -*-
import os
import sys
import threading
import traceback
import signal
import tempfile
from datetime import datetime
import time
import faulthandler


def test():
    while True:
        print(datetime.now())
        time.sleep(2)


def signal_handler(signum, frame):
    try:
        file = os.path.join(tempfile.gettempdir(), datetime.now().strftime('%Y%m%d%H%M%S') + ".log")
        with open(file, 'w+') as f:
            faulthandler.dump_traceback(file=f, all_threads=True)
    except BaseException as e:
        print(e)


if __name__ == "__main__":
    try:
        signal.signal(signal.SIGQUIT, signal_handler)

        threading.Thread(target=test).start()

        while True:
            time.sleep(60)
    except KeyboardInterrupt:
        sys.exit(1)

运行上面的程序,并使用下面的命令来给进程发 SIGQUIT 信号

$ kill -SIGQUIT `ps -ef | grep test.py | grep -v 'grep' | awk '{print $2}'`

然后可以在 /tmp 目录下找到输出的线程日志,内容如下,同时我们也可以看到程序会继续执行下去而不会推出。

Thread 0x00007f13d75d2700 (most recent call first):
  File "./test3.py", line 17 in test
  File "/usr/lib64/python3.4/threading.py", line 859 in run
  File "/usr/lib64/python3.4/threading.py", line 911 in _bootstrap_inner
  File "/usr/lib64/python3.4/threading.py", line 879 in _bootstrap

Current thread 0x00007f13e2171740 (most recent call first):
  File "./test3.py", line 24 in signal_handler
  File "./test3.py", line 36 in <module>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

小解Redis 系列

官网:http://redis.io/ 推荐一个开源组件:StackExchange.Redis https://github.com/StackExchang...

2999
来自专栏大内老A

.NET Core的文件系统[1]:读取并监控文件的变化

ASP.NET Core 具有很多针对文件读取的应用。比如我们倾向于采用JSON文件来定义配置,所以应用就会涉及针对配置文件读取。如果用户发送一个针对物理文件的...

6615
来自专栏王磊的博客

GentleNet使用之详细图解[语法使用增强版]

目录 第一章 开发环境 第二章 简介 第三章 Gentle.Net-1.5.0 下载文件包介绍 第四章 使用步骤 第五章 源码下载 第一章、开发环境: Vs 2...

2849
来自专栏大内老A

从数据到代码——通过代码生成机制实现强类型编程[下篇]

在《上篇》中,我们实现了将保存有消息条目的XML向CodeDOM的转换,即是将XML文件生成一个CodeCompileUnit对象,而该CodeCompileU...

2036
来自专栏代码散人

如何使用Swift Package Manager那么,让我门开始吧

Swift Package Manager 是苹果推出的用于创建使用swift的库和可执行程序的工具。

1664
来自专栏逆向技术

Win3内存管理之私有内存跟共享内存的申请与释放

  通过上一篇文章.我们理解了虚拟内存与物理内存的区别. 那么我们有API事专门申请虚拟内存与物理内存的.

1162
来自专栏大内老A

谈谈你最熟悉的System.DateTime[下篇]

在《上篇》中,我们实现了将保存有消息条目的XML向CodeDOM的转换,即是将XML文件生成一个CodeCompileUnit对象,而该CodeCompileU...

1785
来自专栏谈补锅

iOS之ProtocolBuffer搭建和示例demo

     这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题!

1773
来自专栏NetCore

保护连接字符串

保护连接字符串 摘自MSDN 保护对数据源的访问是安全应用程序最重要的目标之一。为了帮助限制对数据源的访问,必须保护连接信息(例如用户标识、密码和数据源名称)的...

2015
来自专栏Core Net

ASP.NET Core 2.1 : 十二.内置日志、使用Nlog将日志输出到文件

2142

扫码关注云+社区

领取腾讯云代金券