欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

分析運行中的 Python 進程詳細解析

系統 1646 0

在 Java 中打印當前線程的方法棧,可以用 kill -3 命令向 JVM 發送一個 OS 信號,JVM 捕捉以后會自動 dump 出來;當然,也可以直接使用 jstack 工具完成,這些方法好幾年前我在這篇性能分析的文章 中介紹過。這樣的需求可以說很常見,比如定位死鎖,定位一個不工作的線程到底卡在哪里,或者定位為什么 CPU 居高不下等等問題。

現在工作中我用的是 Python,需要線上問題定位的緣故,也有了類似的需求――想要知道當前的 Python 進程“在干什么”。但是沒有了 JVM 的加持,原有的命令或者工具都不再適用。傳統的 gdb 的 debug 大法在線上也不好操作。于是我尋找了一些別的方法,來幫助定位問題,我把它們記錄在這里。

signal

在代碼中,我們可以使用 signal 為進程預先注冊一個信號接收器,在進程接收到特定信號的時候,可以打印方法棧:

            
import traceback, signal
class Debugger():
  def __init__(self, logger):
    self._logger = logger
  def log_stack_trace(self, sig, frame):
    d={'_frame':frame}
    d.update(frame.f_globals)
    d.update(frame.f_locals)
    messages = "Signal received. Stack trace:\n"
    messages += ''.join(traceback.format_stack(frame))
    self._logger.warn(messages)
  def listen(self):
    signal.signal(signal.SIGUSR1, self.log_stack_trace)

          

通過調用上面的 listen 方法(比如 new Debug(logger).listen()),就將一個可以接收 SIGUSR1 并打印方法棧的接收器注冊到當前進程了。這里是打印方法棧,但是實際上可以做任何事,因為方法執行的當前,上下文已經跑到進程里面了。

那么怎么向進程發送信號呢?和 JVM 的方法類似,可以通過操作系統命令來發送:

kill -30 pid

這里的信號為什么是 30?這是因為 SIGUSR1 被當前操作系統定義成 30(請注意不同的操作系統這個映射表是可能不同的),這點可以通過 man signal 查看:

            
No Name Default Action Description
 SIGHUP terminate process terminal line hangup
 SIGINT terminate process interrupt program
 SIGQUIT create core image quit program
 SIGILL create core image illegal instruction
 SIGTRAP create core image trace trap
 SIGABRT create core image abort program (formerly SIGIOT)
 SIGEMT create core image emulate instruction executed
 SIGFPE create core image floating-point exception
 SIGKILL terminate process kill program
 SIGBUS create core image bus error
 SIGSEGV create core image segmentation violation
 SIGSYS create core image non-existent system call invoked
 SIGPIPE terminate process write on a pipe with no reader
 SIGALRM terminate process real-time timer expired
 SIGTERM terminate process software termination signal
 SIGURG discard signal urgent condition present on socket
 SIGSTOP stop process stop (cannot be caught or ignored)
 SIGTSTP stop process stop signal generated from keyboard
 SIGCONT discard signal continue after stop
 SIGCHLD discard signal child status has changed
 SIGTTIN stop process background read attempted from control terminal
 SIGTTOU stop process background write attempted to control terminal
 SIGIO discard signal I/O is possible on a descriptor (see fcntl(2))
 SIGXCPU terminate process cpu time limit exceeded (see setrlimit(2))
 SIGXFSZ terminate process file size limit exceeded (see setrlimit(2))
 SIGVTALRM terminate process virtual time alarm (see setitimer(2))
 SIGPROF terminate process profiling timer alarm (see setitimer(2))
 SIGWINCH discard signal Window size change
 SIGINFO discard signal status request from keyboard
 SIGUSR1 terminate process User defined signal 1
 SIGUSR2 terminate process User defined signal 2

          

當然,也可以寫一點點 python 腳本來發送這個信號:

            
import os, signal
os.kill($PID, signal.SIGUSR1)
          

原理是一樣的。

strace

如果進程已經無響應了,或者上面的信號接收器沒有注冊,那么就要考慮別的方法來或者“進程在干什么”這件事情了。其中,一個有用的命令是 strace:

strace -p pid

比如,我自己寫了一個測試腳本 t.py,使用 python 執行,然后調用 sleep,再給它發送一個 SIGUSR1 的消息,它打印方法棧并退出。這整個過程,我使用 strace 可以得到這樣的結果:

            
strace -p 9157
strace: Process 9157 attached
select(0, NULL, NULL, NULL, {9999943, 62231}) = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=9273, si_uid=9007} ---
rt_sigreturn({mask=[]})         = -1 EINTR (Interrupted system call)
stat("t.py", {st_mode=S_IFREG|0644, st_size=1281, ...}) = 0
open("t.py", O_RDONLY)         = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1281, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=1281, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f631e866000
read(3, "import traceback, signal, time\n "..., 8192) = 1281
read(3, "", 4096)            = 0
close(3)                = 0
munmap(0x7f631e866000, 4096)      = 0
stat("t.py", {st_mode=S_IFREG|0644, st_size=1281, ...}) = 0
write(1, "Signal received. Stack trace:\n "..., 134) = 134
write(1, "\n", 1)            = 1
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f631e06f5d0}, {0x7f631e392680, [], SA_RESTORER, 0x7f631e06f5d0}, 8) = 0
rt_sigaction(SIGUSR1, {SIG_DFL, [], SA_RESTORER, 0x7f631e06f5d0}, {0x7f631e392680, [], SA_RESTORER, 0x7f631e06f5d0}, 8) = 0
exit_group(0)              = ?
+++ exited with 0 +++
          

可以看到從 strace attached 開始,到進程退出,所有重要的調用都被打印出來了。

在 iOS 下,沒有 strace,但是可以使用類似的(更好的)命令 dtruss。

lsof

lsof 可以打印某進程打開的文件,而 Linux 下面一切都是文件,因此查看打開的文件列表有時可以獲取很多額外的信息。比如,打開前面提到的這個測試進程:

            
lsof -p 16872
COMMAND  PID USER  FD  TYPE DEVICE  SIZE/OFF   NODE NAME
Python 16872 xxx cwd  DIR  1,5    2688 1113586 /Users/xxx
Python 16872 xxx txt  REG  1,5   51744 10627527 /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
Python 16872 xxx txt  REG  1,5   52768 10631046 /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_locale.so
Python 16872 xxx txt  REG  1,5   65952 10631134 /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/time.so
Python 16872 xxx txt  REG  1,5   841440 10690598 /usr/lib/dyld
Python 16872 xxx txt  REG  1,5 1170079744 10705794 /private/var/db/dyld/dyld_shared_cache_x86_64h
Python 16872 xxx  0u  CHR  16,2  0t39990   649 /dev/ttys002
Python 16872 xxx  1u  CHR  16,2  0t39990   649 /dev/ttys002
Python 16872 xxx  2u  CHR  16,2  0t39990   649 /dev/ttys002
          

它有幾個參數很常用,比如-i,用來指定網絡文件(如果是“-i: 端口號”這樣的形式還可以指定端口)。

總結

以上所述是小編給大家介紹的分析運行中的 Python 進程,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚州老熟女A片AV色欲小说 | 欧美浮力影院 | 国产精品久久久久久久久久久久久 | 91热久久免费频精品黑人99 | 日韩欧美在线观看视频一区二区 | 欧美特黄aaaaaa| 国产日韩欧美中文字幕 | 九九综合 | 久草网站 | 成人福利视频在线看高清观看 | 成人免费久久精品国产片久久影院 | 少妇特黄a一区二区三区88av | 色片免费在线观看 | 日本一区二区三区精品国产 | 美国黄色毛片 | 鲁一鲁综合| 久久视频这里只精品3国产 色偷偷偷 | 久久99国产精品 | 日韩欧美一区二区三区视频 | 欧美金妇欧美乱妇视频 | 成人精品一区 | 午夜剧场在线免费观看 | 97超级碰碰| 国产小视频在线 | a级片免费视频 | 久热香蕉精品视频在线播放 | 性做久久久久久 | 天天操人人射 | 麻豆国产一区二区三区四区 | 久草免费福利资源站 | 国产精品免费入口视频 | 午夜剧场操一操 | 欧美大片在线观看 | 久久这里只有精品免费看青草 | 中文欧美日韩 | 日本亚洲a| 9966av| 日本久久综合网 | 日产一一到六区麻豆 | 99久久精品国产片 | 99精品在线免费观看 |