網站首頁 編程語言 正文
楔子
Python 有一個第三方模塊叫 psutil,專門用來獲取操作系統以及硬件相關的信息,比如:CPU、磁盤、網絡、內存等等。下面來看一下它的用法,不過在使用之前需要先安裝,直接 pip install psutil 即可。
CPU 相關
獲取 CPU 的邏輯核心數量
import?psutil
print(psutil.cpu_count())??#?12
#?或者使用?multiprocessing
import?multiprocessing
print(multiprocessing.cpu_count()) #?12
獲取 CPU 的物理核心數量
import?psutil
print(psutil.cpu_count(logical=False))??#?6
結果為 6,說明是 6 核超線程;如果 CPU 的物理核心數和邏輯核心數相等,也為 12,則說明是 12 核非超線程。
統計 CPU 的用戶/系統/空閑時間
import?psutil
print(psutil.cpu_times())
"""
scputimes(user=84732.10937499999,?
??????????system=37132.85937500023,?
??????????idle=2003964.1249999998,?
??????????interrupt=3500.765625,?
??????????dpc=1089.6875)
"""
#?還有一個?psutil.cpu_times_percent()?
#?功能與之類似,?只不過返回的是比例
該函數返回的是一個 namedtuple,后面凡是結構長的和這里類似的,都是 namedtuple。補充一下,如果你的程序中需要創建大量的對象,并且該對象的屬性固定不變,那么不妨使用 namedtuple,相比使用字典,能節省大量空間。
查看 CPU 的使用率
import?psutil
for?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?的邏輯數量是?12
#?所以每個列表里面有?12?個元素
查看 CPU 的統計信息
包括上下文切換、中斷、軟中斷,以及系統調用次數等等。
import?psutil
print(psutil.cpu_stats())
"""
scpustats(ctx_switches=3346512902,?
??????????interrupts=2288572793,?
??????????soft_interrupts=0,?
??????????syscalls=3324041552)
"""
查看 CPU 的頻率
import?psutil
print(psutil.cpu_freq())
"""
scpufreq(current=2208.0,?min=0.0,?max=2208.0)
"""
內存相關
查看內存使用情況
import?psutil
print(psutil.virtual_memory())
"""
svmem(total=17029259264,?
??????available=7698505728,?
??????percent=54.8,?
??????used=9330753536,?
??????free=7698505728)
"""
total 表示總內存,available 表示可用內存,percent 表示內存使用率,used 表示已使用的內存,free 表示可用內存。
所以 available 加上 used 等于?total,used 除以 total 再乘以 100 等于 percent。
查看交換內存信息
import?psutil
print(psutil.swap_memory())
"""
sswap(total=3087007744,?
??????used=4509839360,?
??????free=-1422831616,?
??????percent=146.1,?
??????sin=0,?
??????sout=0)
"""
說到內存,有物理內存、交換內存、虛擬內存,這三者有什么區別呢?用大白話解釋就是:
1)物理內存是實際的內存條提供的臨時數據存儲空間,在 Windows 上右鍵點擊計算機,再點擊屬性時,上面顯示的安裝內存(RAM)就是電腦的物理內存。這些內存是實際存在的,在你不給機器增加內存條的時候是不會改變的。
2)交換內存通常在頁面調度和交換進程數據時使用,相當于在進行內存整理的時候,會先把部分數據放在硬盤的某塊區域。類似我們整理衣柜,衣服一多直接整理會很麻煩,因此會先把部分衣服拿出來放在其它地方,等衣柜里的衣服整理完了,再把放在其它地方的衣服拿回來。
這個其它地方在計算機中則代表硬盤的某塊區域,也就是我們所說的交換區。通常使用交換內存是因為物理內存不足導致的,正所謂衣柜,如果足夠大的話就沒必要拿出部分衣服放在其它地方, 直接在衣柜里就能解決了。
3)最后是虛擬內存,當操作文件,可執行程序等等,那么首先要把它們從磁盤讀取到內存中,因此 CPU 除了自己那一部分小小的空間外,要想操作數據,只能操作內存里的數據。
但是當內存不夠了,那么會在硬盤上開辟一份虛擬內存,將物理內存里的部分數據放在虛擬內存當中。硬盤的空間很大,即使普通電腦安裝的固態硬盤也有一百個 G,因此可以拿出一部分充當虛擬內存。
不過虛擬內存雖說是內存,但畢竟在硬盤上,速度和 CPU 直接從物理內存里讀取數據相差甚遠。這也是為什么要將經常被訪問的熱點數據放在 Redis 緩存里,而不是放在硬盤或者數據庫上。
磁盤相關
查看磁盤分區、磁盤使用率和磁盤 IO 信息
import?psutil
print(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 表示文件系統類型,這里是 NTFS;opts 中的 rw 表示可讀寫。
該函數還可以接收一個參數 all,默認為 False。如果指定為 True,在 Linux 上返回的內容還會包含 /proc 等特殊文件系統的掛載信息。由于我這里是 Windows,所以兩者沒區別。
查看某個磁盤使用情況
import?psutil
print(psutil.disk_usage("C:\\"))
"""
sdiskusage(total=267117391872,?
???????????used=96894304256,?
???????????free=170223087616,?
???????????percent=36.3)
"""
查看磁盤 IO 統計信息
import?psutil
print(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 :讀次數
- write_count:寫次數
- read_bytes:讀的字節數
- write_bytes:寫的字節數
- read_time:讀時間
- write_time:寫時間
以上返回的是所有磁盤加起來的統計信息,我們可以指定 perdisk=True,分別列出每一個分區的統計信息。
網絡相關
查看網卡的網絡 IO 統計信息
import?psutil
print(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:?發送的字節數
#?bytes_recv:?接收的字節數
#?packets_sent:?發送的包數據量
#?packets_recv:?接收的包數據量
#?errin:?接收包時,?出錯的次數
#?errout:?發送包時,?出錯的次數
#?dropin:?接收包時,?丟棄的次數
#?dropout:?發送包時,?丟棄的次數
#?里面還有一個?pernic?參數
#?如果為?True,?則列出所有網卡的信息
print(psutil.net_io_counters(pernic=True))
"""
{'以太網':?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),?
'藍牙網絡連接':?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)}
"""
查看網絡接口信息
import?psutil
#?以字典的形式返回網卡的配置信息
#?包括?IP?地址、Mac地址、子網掩碼、廣播地址等等
print(psutil.net_if_addrs())
"""
{'以太網':?[
????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':?[...],?
'藍牙網絡連接':?[...],?
'Loopback?Pseudo-Interface?1':?[...]}
"""
#?返回網卡的詳細信息,?包括是否啟動、通信類型、傳輸速度、mtu
print(psutil.net_if_stats())
"""
{'以太網':?snicstats(isup=True,?
????????????????????duplex=<NicDuplex.NIC_DUPLEX_FULL:?2>,?
????????????????????speed=1000,?mtu=1500),?
'藍牙網絡連接':?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)}
"""
查看當前機器的網絡連接
import?psutil
#?以列表的形式返回每個網絡連接的詳細信息
#?里面接受一個參數,?默認是?"inet"
#?當然我們也可以指定為其它,?比如?"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。另外該函數會返回所有的連接信息,所以當連接數很多的時候,會占用較高的內存。
查看當前登錄的用戶信息
import?psutil
print(psutil.users())
"""
[suser(name='satori',?terminal=None,?host='0.0.0.0',?
???????started=1609841661.0,?pid=None)]
"""
查看系統的啟動時間
import?psutil
from?datetime?import?datetime
print(psutil.boot_time())??#?1654012221.2945454
print(
????datetime.fromtimestamp(psutil.boot_time())
)??#?2022-05-31?23:50:21.294545
進程管理
psutil 還提供了很多和進程管理相關的功能函數,非常的豐富,我們來看一下。
查看當前存在的所有進程的 pid
import?psutil
print(psutil.pids())
"""
[0,?4,?148,?532,?668,?796,?904,?912,?976,?...]
"""
查看某個進程是否存在
import?psutil
print(psutil.pid_exists(22333))??#?False
print(psutil.pid_exists(532))??#?True
返回所有進程(Process)對象組成的迭代器
import?psutil
print(psutil.process_iter())
"""
<generator?object?process_iter?at?0x000...>
"""
#?遍歷的話,會得到每一個進程對象
#?進程對象在?psutil?里面的類型是?Process
根據 pid 獲取一個進程對應的 Process 對象
import?psutil
print(psutil.Process(14124))
"""
psutil.Process(pid=14124,?name='WeChat.exe',?
???????????????status='running',?started='10:54:43')
"""
#?進程名稱是?WeChat.exe,狀態為運行中
#?啟動時間是早上?10?點?54?分
進程管理操作
我們說根據 pid 可以獲取一個進程對應的 Process 對象,而這個對象里面包含了該進程的全部信息。
import?psutil
p?=?psutil.Process(14124)
#?進程名稱
print(p.name())
"""
WeChat.exe
"""
#?進程的exe路徑
print(p.exe())
"""
D:\WeChat\WeChat.exe
"""
#?進程的工作目錄
print(p.cwd())
"""
D:\WeChat
"""
#?進程啟動的命令行
print(p.cmdline())
"""
['D:\\WeChat\\WeChat.exe']
"""
#?當前進程id
print(p.pid)
"""
14124
"""
#?父進程id
print(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')]
"""
#?進程狀態
print(p.status())
"""
running
"""
#?進程用戶名
print(p.username())
"""
LAPTOP-264ORES3\satori
"""
#?進程創建時間,返回時間戳
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)
"""
#?進程所使用的的內存
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())
#?進程相關的網絡連接
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')]
"""
#?進程內的線程數量,這個進程開啟了多少個線程
print(p.num_threads())??#?58
#?這個進程內的所有線程信息
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),
?...?
?]
"""
#?進程的環境變量
print(p.environ())
#?結束進程
#?執行之后微信就會被強制關閉,?這里就不試了
#?p.terminal()
我們還可以調用 psutil.test 來模擬 ps 命令。
import?psutil
psutil.test()
輸出如下:
它是怎么做的呢?還記得我們之前說的 process_iter 嗎?會返回所有進程的 Process 對象,直接依次輸出里面的信息即可。同理,我們也可以通過 process_iter 找到某一個進程對應的進程 id。
import?psutil
for?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')
"""
有了這個操作之后,我們便可以找到對應的進程,然后借助操作系統的 kernal 修改進程內部的數據。
原文鏈接:https://mp.weixin.qq.com/s/aBNlRj2DF2B9cMCbjb7sww
相關推薦
- 2022-10-02 react中使用antd及immutable示例詳解_React
- 2022-12-07 【Chrome】瀏覽器控制臺設置成中文
- 2022-09-10 PyCharm新建.py文件時默認添加信息的實現_python
- 2023-01-26 如何在.Net?7中將Query綁定到數組詳解_實用技巧
- 2022-10-04 C語言實現倒置字符串的兩種方法分享_C 語言
- 2022-07-12 for循環中var和let的不為人知的秘密
- 2022-04-19 C#多線程系列之線程的創建和生命周期_C#教程
- 2023-01-19 GO語言的map類型實例詳解_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支