您好,登錄后才能下訂單哦!
這篇文章主要介紹Python中如何查看當(dāng)前的進(jìn)程在干什么,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
signal
在代碼中,我們可以使用 signal 為進(jìn)程預(yù)先注冊(cè)一個(gè)信號(hào)接收器,在進(jìn)程接收到特定信號(hào)的時(shí)候,可以打印方法棧:
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)
通過(guò)調(diào)用上面的 listen 方法(比如 new Debug(logger).listen()),就將一個(gè)可以接收 SIGUSR1 并打印方法棧的接收器注冊(cè)到當(dāng)前進(jìn)程了。這里是打印方法棧,但是實(shí)際上可以做任何事,因?yàn)榉椒▓?zhí)行的當(dāng)前,上下文已經(jīng)跑到進(jìn)程里面了。
那么怎么向進(jìn)程發(fā)送信號(hào)呢?和 JVM 的方法類(lèi)似,可以通過(guò)操作系統(tǒng)命令來(lái)發(fā)送:
kill -30 pid
這里的信號(hào)為什么是 30?這是因?yàn)?SIGUSR1 被當(dāng)前操作系統(tǒng)定義成 30(請(qǐng)注意不同的操作系統(tǒng)這個(gè)映射表是可能不同的),這點(diǎn)可以通過(guò) 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
當(dāng)然,也可以寫(xiě)一點(diǎn)點(diǎn) python 腳本來(lái)發(fā)送這個(gè)信號(hào):
import os, signal os.kill($PID, signal.SIGUSR1)
原理是一樣的。
strace
如果進(jìn)程已經(jīng)無(wú)響應(yīng)了,或者上面的信號(hào)接收器沒(méi)有注冊(cè),那么就要考慮別的方法來(lái)或者“進(jìn)程在干什么”這件事情了。其中,一個(gè)有用的命令是 strace:
strace -p pid
比如,我自己寫(xiě)了一個(gè)測(cè)試腳本 t.py,使用 python 執(zhí)行,然后調(diào)用 sleep,再給它發(fā)送一個(gè) SIGUSR1 的消息,它打印方法棧并退出。這整個(gè)過(guò)程,我使用 strace 可以得到這樣的結(jié)果:
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 開(kāi)始,到進(jìn)程退出,所有重要的調(diào)用都被打印出來(lái)了。
在 iOS 下,沒(méi)有 strace,但是可以使用類(lèi)似的(更好的)命令 dtruss。
lsof
lsof 可以打印某進(jìn)程打開(kāi)的文件,而 Linux 下面一切都是文件,因此查看打開(kāi)的文件列表有時(shí)可以獲取很多額外的信息。比如,打開(kāi)前面提到的這個(gè)測(cè)試進(jìn)程:
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
它有幾個(gè)參數(shù)很常用,比如-i,用來(lái)指定網(wǎng)絡(luò)文件(如果是“-i: 端口號(hào)”這樣的形式還可以指定端口)。
以上是“Python中如何查看當(dāng)前的進(jìn)程在干什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。