目錄
楔子
Python 有一個第三方模塊叫 psutil,專門用來獲取操作系統(tǒng)以及硬件相關(guān)得信息,比如:CPU、磁盤、網(wǎng)絡(luò)、內(nèi)存等等。下面來看一下它得用法,不過在使用之前需要先安裝,直接 pip install psutil 即可。
CPU 相關(guān)
獲取 CPU 得邏輯核心數(shù)量
import?psutilprint(psutil.cpu_count())??#?12#?或者使用?multiprocessingimport?multiprocessingprint(multiprocessing.cpu_count()) #?12
獲取 CPU 得物理核心數(shù)量
import?psutilprint(psutil.cpu_count(logical=False))??#?6
結(jié)果為 6,說明是 6 核超線程;如果 CPU 得物理核心數(shù)和邏輯核心數(shù)相等,也為 12,則說明是 12 核非超線程。
統(tǒng)計 CPU 得用戶/系統(tǒng)/空閑時間
import?psutilprint(psutil.cpu_times())"""scputimes(user=84732.10937499999,???????????system=37132.85937500023,???????????idle=2003964.1249999998,???????????interrupt=3500.765625,???????????dpc=1089.6875)"""#?還有一個?psutil.cpu_times_percent()?#?功能與之類似,?只不過返回得是比例
該函數(shù)返回得是一個 namedtuple,后面凡是結(jié)構(gòu)長得和這里類似得,都是 namedtuple。補充一下,如果你得程序中需要創(chuàng)建大量得對象,并且該對象得屬性固定不變,那么不妨使用 namedtuple,相比使用字典,能節(jié)省大量空間。
查看 CPU 得使用率
import?psutilfor?x?in?range(3):????# interval:表示每隔?0.5s 刷新一次????# percpu:為 True 表示查看所有得 cpu 使用率????print(psutil.cpu_percent(interval=0.5,?percpu=True))"""[9.1,?3.1,?12.5,?3.1,?15.6,?0.0,?6.2,?0.0,?12.5,?50.0,?9.4,?3.1][9.1,?6.2,?12.5,?6.2,?3.1,?0.0,?0.0,?3.1,?0.0,?15.6,?3.1,?0.0][0.0,?0.0,?15.6,?0.0,?6.2,?0.0,?6.2,?25.0,?3.1,?9.4,?6.2,?0.0]"""#?我這里?cpu?得邏輯數(shù)量是?12#?所以每個列表里面有?12?個元素
查看 CPU 得統(tǒng)計信息
包括上下文切換、中斷、軟中斷,以及系統(tǒng)調(diào)用次數(shù)等等。
import?psutilprint(psutil.cpu_stats())"""scpustats(ctx_switches=3346512902,???????????interrupts=2288572793,???????????soft_interrupts=0,???????????syscalls=3324041552)"""
查看 CPU 得頻率
import?psutilprint(psutil.cpu_freq())"""scpufreq(current=2208.0,?min=0.0,?max=2208.0)"""
內(nèi)存相關(guān)
查看內(nèi)存使用情況
import?psutilprint(psutil.virtual_memory())"""svmem(total=17029259264,???????available=7698505728,???????percent=54.8,???????used=9330753536,???????free=7698505728)"""
total 表示總內(nèi)存,available 表示可用內(nèi)存,percent 表示內(nèi)存使用率,used 表示已使用得內(nèi)存,free 表示可用內(nèi)存。
所以 available 加上 used 等于 total,used 除以 total 再乘以 100 等于 percent。
查看交換內(nèi)存信息
import?psutilprint(psutil.swap_memory())"""sswap(total=3087007744,???????used=4509839360,???????free=-1422831616,???????percent=146.1,???????sin=0,???????sout=0)"""
說到內(nèi)存,有物理內(nèi)存、交換內(nèi)存、虛擬內(nèi)存,這三者有什么區(qū)別呢?用大白話解釋就是:
1)物理內(nèi)存是實際得內(nèi)存條提供得臨時數(shù)據(jù)存儲空間,在 Windows 上右鍵點擊計算機,再點擊屬性時,上面顯示得安裝內(nèi)存(RAM)就是電腦得物理內(nèi)存。這些內(nèi)存是實際存在得,在你不給機器增加內(nèi)存條得時候是不會改變得。
2)交換內(nèi)存通常在頁面調(diào)度和交換進程數(shù)據(jù)時使用,相當(dāng)于在進行內(nèi)存整理得時候,會先把部分數(shù)據(jù)放在硬盤得某塊區(qū)域。類似我們整理衣柜,衣服一多直接整理會很麻煩,因此會先把部分衣服拿出來放在其它地方,等衣柜里得衣服整理完了,再把放在其它地方得衣服拿回來。
這個其它地方在計算機中則代表硬盤得某塊區(qū)域,也就是我們所說得交換區(qū)。通常使用交換內(nèi)存是因為物理內(nèi)存不足導(dǎo)致得,正所謂衣柜,如果足夠大得話就沒必要拿出部分衣服放在其它地方, 直接在衣柜里就能解決了。
3)最后是虛擬內(nèi)存,當(dāng)操作文件,可執(zhí)行程序等等,那么首先要把它們從磁盤讀取到內(nèi)存中,因此 CPU 除了自己那一部分小小得空間外,要想操作數(shù)據(jù),只能操作內(nèi)存里得數(shù)據(jù)。
但是當(dāng)內(nèi)存不夠了,那么會在硬盤上開辟一份虛擬內(nèi)存,將物理內(nèi)存里得部分數(shù)據(jù)放在虛擬內(nèi)存當(dāng)中。硬盤得空間很大,即使普通電腦安裝得固態(tài)硬盤也有一百個 G,因此可以拿出一部分充當(dāng)虛擬內(nèi)存。
不過虛擬內(nèi)存雖說是內(nèi)存,但畢竟在硬盤上,速度和 CPU 直接從物理內(nèi)存里讀取數(shù)據(jù)相差甚遠。這也是為什么要將經(jīng)常被訪問得熱點數(shù)據(jù)放在 Redis 緩存里,而不是放在硬盤或者數(shù)據(jù)庫上。
磁盤相關(guān)
查看磁盤分區(qū)、磁盤使用率和磁盤 IO 信息
import?psutilprint(psutil.disk_partitions())"""[sdiskpart(device='C:\',?mountpoint='C:\',?fstype='NTFS',?opts='rw,fixed',?maxfile=255,?maxpath=260),?sdiskpart(device='D:\',?mountpoint='D:\',?fstype='NTFS',?opts='rw,fixed',?maxfile=255,?maxpath=260),?sdiskpart(device='E:\',?mountpoint='E:\',?fstype='NTFS',?opts='rw,fixed',?maxfile=255,?maxpath=260)]"""
可以看到一共有三個盤符,fstype 表示文件系統(tǒng)類型,這里是 NTFS;opts 中得 rw 表示可讀寫。
該函數(shù)還可以接收一個參數(shù) all,默認為 False。如果指定為 True,在 Linux 上返回得內(nèi)容還會包含 /proc 等特殊文件系統(tǒng)得掛載信息。由于我這里是 Windows,所以兩者沒區(qū)別。
查看某個磁盤使用情況
import?psutilprint(psutil.disk_usage("C:\"))"""sdiskusage(total=267117391872,????????????used=96894304256,????????????free=170223087616,????????????percent=36.3)"""
查看磁盤 IO 統(tǒng)計信息
import?psutilprint(psutil.disk_io_counters())"""sdiskio(read_count=1172461,?????????write_count=2153031,?????????read_bytes=36854982144,?????????write_bytes=52718300160,?????????read_time=551,?????????write_time=1437)"""
- read_count :讀次數(shù)
- write_count:寫次數(shù)
- read_bytes:讀得字節(jié)數(shù)
- write_bytes:寫得字節(jié)數(shù)
- read_time:讀時間
- write_time:寫時間
以上返回得是所有磁盤加起來得統(tǒng)計信息,我們可以指定 perdisk=True,分別列出每一個分區(qū)得統(tǒng)計信息。
網(wǎng)絡(luò)相關(guān)
查看網(wǎng)卡得網(wǎng)絡(luò) IO 統(tǒng)計信息
import?psutilprint(psutil.net_io_counters())"""snetio(bytes_sent=175995567,????????bytes_recv=2849015622,????????packets_sent=1052206,????????packets_recv=3050302,????????errin=0,????????errout=0,????????dropin=3491,????????dropout=0)"""#?bytes_sent:?發(fā)送得字節(jié)數(shù)#?bytes_recv:?接收得字節(jié)數(shù)#?packets_sent:?發(fā)送得包數(shù)據(jù)量#?packets_recv:?接收得包數(shù)據(jù)量#?errin:?接收包時,?出錯得次數(shù)#?errout:?發(fā)送包時,?出錯得次數(shù)#?dropin:?接收包時,?丟棄得次數(shù)#?dropout:?發(fā)送包時,?丟棄得次數(shù)#?里面還有一個?pernic?參數(shù)#?如果為?True,?則列出所有網(wǎng)卡得信息print(psutil.net_io_counters(pernic=True))"""{'以太網(wǎng)':?snetio(bytes_sent=178716616,??????????????????bytes_recv=2866823348,??????????????????packets_sent=1058190,??????????????????packets_recv=3102852,??????????????????errin=0,?errout=0,??????????????????dropin=3491,?dropout=0),?'WLAN':?snetio(bytes_sent=0,?bytes_recv=0,????????????????packets_sent=0,?packets_recv=0,????????????????errin=0,?errout=0,????????????????dropin=0,?dropout=0),?'本地連接*?3':?snetio(bytes_sent=0,?bytes_recv=0,?????????????????????packets_sent=0,?packets_recv=0,?????????????????????errin=0,?errout=0,?????????????????????dropin=0,?dropout=0),?'本地連接*?4':?snetio(bytes_sent=0,?bytes_recv=0,??????????????????????packets_sent=0,?packets_recv=0,?????????????????????errin=0,?errout=0,??????????????????????dropin=0,?dropout=0),?'藍牙網(wǎng)絡(luò)連接':?snetio(bytes_sent=0,?bytes_recv=0,?????????????????????packets_sent=0,?packets_recv=0,????????????????????errin=0,?errout=0,?????????????????????dropin=0,?dropout=0),?'Loopback?Pseudo-Interface?1':?snetio(bytes_sent=0,???????????????????????????????????????bytes_recv=0,???????????????????????????????????????packets_sent=0,???????????????????????????????????????packets_recv=0,???????????????????????????????????????errin=0,?errout=0,???????????????????????????????????????dropin=0,?dropout=0)}"""
查看網(wǎng)絡(luò)接口信息
import?psutil#?以字典得形式返回網(wǎng)卡得配置信息#?包括?IP?地址、Mac地址、子網(wǎng)掩碼、廣播地址等等print(psutil.net_if_addrs())"""{'以太網(wǎng)':?[????snicaddr(family=<AddressFamily.AF_LINK:?-1>,??????????????address='9C-7B-EF-15-FC-2F',?netmask=None,??????????????broadcast=None,?ptp=None),?????snicaddr(family=<AddressFamily.AF_INET:?2>,??????????????address='192.168.4.150',?netmask='255.255.240.0',??????????????broadcast=None,?ptp=None),?????snicaddr(family=<AddressFamily.AF_INET6:?23>,??????????????address='fe80::4826:a6a6:b5f4:3647',??????????????netmask=None,?broadcast=None,?ptp=None)],?'WLAN':?[...],?'本地連接*?3':?[...],?'本地連接*?4':?[...],?'藍牙網(wǎng)絡(luò)連接':?[...],?'Loopback?Pseudo-Interface?1':?[...]}"""#?返回網(wǎng)卡得詳細信息,?包括是否啟動、通信類型、傳輸速度、mtuprint(psutil.net_if_stats())"""{'以太網(wǎng)':?snicstats(isup=True,?????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,?????????????????????speed=1000,?mtu=1500),?'藍牙網(wǎng)絡(luò)連接':?snicstats(isup=False,?????????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,?????????????????????????speed=3,?mtu=1500),?'Loopback?Pseudo-Interface?1':?snicstats(isup=True,??????????????????????????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,??????????????????????????????????????????speed=1073,?mtu=1500),?'WLAN':?snicstats(isup=False,???????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,???????????????????speed=0,?mtu=1500),?'本地連接*?3':?snicstats(isup=False,?????????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,?????????????????????????speed=0,?mtu=1500),?'本地連接*?4':?snicstats(isup=False,?????????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,?????????????????????????speed=0,?mtu=1500)}"""
查看當(dāng)前機器得網(wǎng)絡(luò)連接
import?psutil#?以列表得形式返回每個網(wǎng)絡(luò)連接得詳細信息#?里面接受一個參數(shù),?默認是?"inet"#?當(dāng)然我們也可以指定為其它,?比如?"tcp"print(psutil.net_connections())"""[sconn(fd=-1,?family=<AddressFamily.AF_INET:?2>,????????type=<SocketKind.SOCK_DGRAM:?2>,????????laddr=addr(ip='192.168.4.150',?port=137),????????raddr=(),?status='NONE',?pid=4),?sconn(fd=-1,?family=<AddressFamily.AF_INET:?2>,????????type=<SocketKind.SOCK_DGRAM:?2>,????????laddr=addr(ip='127.0.0.1',?port=54872),????????raddr=(),?status='NONE',?pid=11652),?sconn(fd=-1,?family=<AddressFamily.AF_INET:?2>,????????type=<SocketKind.SOCK_STREAM:?1>,????????laddr=addr(ip='192.168.4.150',?port=11253),????????raddr=addr(ip='117.50.19.136',?port=80),????????status='CLOSE_WAIT',?pid=11568),?....?....?....]"""
是不是很方便呢?在 Linux 中有兩個命令可以做到這一點,分別是 netstat 和 ss。另外該函數(shù)會返回所有得連接信息,所以當(dāng)連接數(shù)很多得時候,會占用較高得內(nèi)存。
查看當(dāng)前登錄得用戶信息
import?psutilprint(psutil.users())"""[suser(name='satori',?terminal=None,?host='0.0.0.0',????????started=1609841661.0,?pid=None)]"""
查看系統(tǒng)得啟動時間
import?psutilfrom?datetime?import?datetimeprint(psutil.boot_time())??#?1654012221.2945454print(????datetime.fromtimestamp(psutil.boot_time()))??#?2022-05-31?23:50:21.294545
進程管理
psutil 還提供了很多和進程管理相關(guān)得功能函數(shù),非常得豐富,我們來看一下。
查看當(dāng)前存在得所有進程得 pid
import?psutilprint(psutil.pids())"""[0,?4,?148,?532,?668,?796,?904,?912,?976,?...]"""
查看某個進程是否存在
import?psutilprint(psutil.pid_exists(22333))??#?Falseprint(psutil.pid_exists(532))??#?True
返回所有進程(Process)對象組成得迭代器
import?psutilprint(psutil.process_iter())"""<generator?object?process_iter?at?0x000...>"""#?遍歷得話,會得到每一個進程對象#?進程對象在?psutil?里面得類型是?Process
根據(jù) pid 獲取一個進程對應(yīng)得 Process 對象
import?psutilprint(psutil.Process(14124))"""psutil.Process(pid=14124,?name='WeChat.exe',????????????????status='running',?started='10:54:43')"""#?進程名稱是?WeChat.exe,狀態(tài)為運行中#?啟動時間是早上?10?點?54?分
進程管理操作
我們說根據(jù) pid 可以獲取一個進程對應(yīng)得 Process 對象,而這個對象里面包含了該進程得全部信息。
import?psutilp?=?psutil.Process(14124)#?進程名稱print(p.name())"""WeChat.exe"""#?進程得exe路徑print(p.exe())"""D:WeChatWeChat.exe"""#?進程得工作目錄print(p.cwd())"""D:WeChat"""#?進程啟動得命令行print(p.cmdline())"""['D:\WeChat\WeChat.exe']"""#?當(dāng)前進程idprint(p.pid)"""14124"""#?父進程idprint(p.ppid())"""8860"""#?父進程print(p.parent())"""psutil.Process(pid=8860,?name='explorer.exe',????????????????status='running',?started='10:53:58')"""#?子進程列表print(p.children())"""[psutil.Process(pid=6852,?name='WechatBrowser.exe',?????????????????status='running',?started='10:54:59'),??psutil.Process(pid=1960,?name='WeChatPlayer.exe',????????????????status='running',?started='10:54:59'),??psutil.Process(pid=10432,?name='WeChatApp.exe',?????????????????status='running',?started='10:55:33')]"""#?進程狀態(tài)print(p.status())"""running"""#?進程用戶名print(p.username())"""LAPTOP-264ORES3satori"""#?進程創(chuàng)建時間,返回時間戳print(p.create_time())"""1654570483.2370846"""#?進程終端#?在windows上無法使用try:????print(p.terminal())except?Exception?as?e:????print(e)"""'Process'?object?has?no?attribute?'terminal'"""#?進程使用得cpu時間print(p.cpu_times())"""pcputimes(user=27.8125,?system=13.484375,??????????children_user=0.0,?children_system=0.0)"""#?進程所使用得得內(nèi)存print(p.memory_info())"""pmem(rss=110141440,?vms=116899840,??????num_page_faults=661356,?peak_wset=221048832,??????wset=110141440,?peak_paged_pool=834824,??????paged_pool=806216,?peak_nonpaged_pool=144584,??????nonpaged_pool=78560,?pagefile=116899840,??????peak_pagefile=197505024,?private=116899840)"""#?進程打開得文件print(p.open_files())#?進程相關(guān)得網(wǎng)絡(luò)連接print(p.connections())"""[pconn(fd=-1,?family=<AddressFamily.AF_INET:?2>,????????type=<SocketKind.SOCK_STREAM:?1>,????????laddr=addr(ip='192.168.4.150',?port=7693),????????raddr=addr(ip='58.251.111.106',?port=8080),????????status='ESTABLISHED'),??pconn(fd=-1,?family=<AddressFamily.AF_INET:?2>,????????type=<SocketKind.SOCK_STREAM:?1>,????????laddr=addr(ip='127.0.0.1',?port=8680),????????raddr=(),?status='LISTEN')]"""#?進程內(nèi)得線程數(shù)量,這個進程開啟了多少個線程print(p.num_threads())??#?58#?這個進程內(nèi)得所有線程信息print(p.threads())"""[pthread(id=14128,?user_time=11.3125,?system_time=7.578125),??pthread(id=13428,?user_time=0.0,?system_time=0.0),??pthread(id=13616,?user_time=0.0,?system_time=0.0),??pthread(id=13600,?user_time=0.015625,?system_time=0.328125),?pthread(id=7364,?user_time=0.078125,?system_time=0.015625),?...??]"""#?進程得環(huán)境變量print(p.environ())#?結(jié)束進程#?執(zhí)行之后微信就會被強制關(guān)閉,?這里就不試了#?p.terminal()
我們還可以調(diào)用 psutil.test 來模擬 ps 命令。
import?psutilpsutil.test()
輸出如下:
它是怎么做得呢?還記得我們之前說得 process_iter 嗎?會返回所有進程得 Process 對象,直接依次輸出里面得信息即可。同理,我們也可以通過 process_iter 找到某一個進程對應(yīng)得進程 id。
import?psutilfor?prcs?in?psutil.process_iter():????if?prcs.name().lower()?==?"wechat.exe":????????print(prcs)"""psutil.Process(pid=14124,?name='WeChat.exe',????????????????status='running',?started='10:54:43')"""
有了這個操作之后,我們便可以找到對應(yīng)得進程,然后借助操作系統(tǒng)得 kernal 修改進程內(nèi)部得數(shù)據(jù)。
到此這篇關(guān)于Python利用psutil實現(xiàn)獲取硬件,網(wǎng)絡(luò)和進程信息得內(nèi)容就介紹到這了,更多相關(guān)Python psutil獲取信息內(nèi)容請搜索之家以前得內(nèi)容或繼續(xù)瀏覽下面得相關(guān)內(nèi)容希望大家以后多多支持之家!