pmonitor 1.4.9__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- monitor/monitor_mac_vmmap.py +107 -42
- monitor/monitor_pids.py +11 -4
- {pmonitor-1.4.9.dist-info → pmonitor-1.5.0.dist-info}/METADATA +1 -1
- {pmonitor-1.4.9.dist-info → pmonitor-1.5.0.dist-info}/RECORD +7 -7
- {pmonitor-1.4.9.dist-info → pmonitor-1.5.0.dist-info}/WHEEL +0 -0
- {pmonitor-1.4.9.dist-info → pmonitor-1.5.0.dist-info}/entry_points.txt +0 -0
- {pmonitor-1.4.9.dist-info → pmonitor-1.5.0.dist-info}/top_level.txt +0 -0
monitor/monitor_mac_vmmap.py
CHANGED
|
@@ -1,51 +1,116 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
import json
|
|
1
5
|
import re
|
|
2
|
-
import
|
|
6
|
+
import os
|
|
3
7
|
|
|
4
8
|
|
|
5
9
|
class VmMapMemory:
|
|
6
10
|
def __init__(self):
|
|
7
|
-
|
|
11
|
+
"""
|
|
12
|
+
初始化实时内存监控器
|
|
13
|
+
"""
|
|
14
|
+
self.pids = set() # 当前监控的 PID
|
|
15
|
+
self.current_data = {} # 存储最新的内存数据 {pid: memory_mb}
|
|
16
|
+
self.lock = threading.Lock() # 线程锁
|
|
17
|
+
self.running = True # 控制线程运行状态
|
|
18
|
+
self.thread = None # 监控线程
|
|
19
|
+
# 启动监控线程
|
|
20
|
+
self.start_monitoring()
|
|
21
|
+
|
|
22
|
+
def start_monitoring(self):
|
|
23
|
+
"""启动监控线程"""
|
|
24
|
+
self.thread = threading.Thread(target=self._monitor_memory)
|
|
25
|
+
self.thread.daemon = True # 设置为守护线程
|
|
26
|
+
self.thread.start()
|
|
27
|
+
|
|
28
|
+
def update_pids(self, new_pids):
|
|
29
|
+
"""更新要监控的 PID 列表"""
|
|
30
|
+
with self.lock:
|
|
31
|
+
# 转换为字符串并更新集合
|
|
32
|
+
self.pids = set(map(str, new_pids))
|
|
33
|
+
|
|
34
|
+
def _convert_to_mb(self, mem_str):
|
|
35
|
+
"""
|
|
36
|
+
将内存字符串转换为 MB
|
|
37
|
+
支持格式: 123, 123K, 123M, 123G
|
|
38
|
+
"""
|
|
39
|
+
# 移除逗号(如果存在)
|
|
40
|
+
mem_str = mem_str.replace(',', '')
|
|
41
|
+
|
|
42
|
+
# 检查单位并转换
|
|
43
|
+
if 'G' in mem_str:
|
|
44
|
+
return float(mem_str.replace('G', '')) * 1024
|
|
45
|
+
elif 'M' in mem_str:
|
|
46
|
+
return float(mem_str.replace('M', ''))
|
|
47
|
+
elif 'K' in mem_str:
|
|
48
|
+
return float(mem_str.replace('K', '')) / 1024
|
|
49
|
+
else:
|
|
50
|
+
# 假设为字节
|
|
51
|
+
return float(mem_str) / (1024 * 1024)
|
|
52
|
+
|
|
53
|
+
def _monitor_memory(self):
|
|
54
|
+
"""线程函数:实时监控内存使用"""
|
|
55
|
+
# macOS 专用 top 命令
|
|
56
|
+
cmd = ["top", "-stats", "pid,mem"]
|
|
57
|
+
|
|
58
|
+
# 启动 top 进程
|
|
59
|
+
process = subprocess.Popen(
|
|
60
|
+
cmd,
|
|
61
|
+
stdout=subprocess.PIPE,
|
|
62
|
+
stderr=subprocess.PIPE,
|
|
63
|
+
text=True,
|
|
64
|
+
bufsize=1, # 行缓冲
|
|
65
|
+
universal_newlines=True # 确保文本模式
|
|
66
|
+
)
|
|
8
67
|
|
|
9
|
-
async def get_process_memory(self, pid):
|
|
10
|
-
cmd = ["top", "-l", "1", "-stats", "mem", "-pid", str(pid)]
|
|
11
68
|
try:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
last_line = lines[-1].strip() # 获取最后一行
|
|
32
|
-
match = re.match(r'^([\d.]+)([GMK]?)$', last_line)
|
|
33
|
-
|
|
34
|
-
if match:
|
|
35
|
-
val, unit = float(match.group(1)), match.group(2)
|
|
36
|
-
memory_value = val * {
|
|
37
|
-
'G': 1024, 'M': 1, 'K': 1 / 1024, '': 1 / (1024 * 1024)
|
|
38
|
-
}.get(unit, 1)
|
|
39
|
-
|
|
40
|
-
if memory_value > 0:
|
|
41
|
-
self.last_nonzero_memory = memory_value
|
|
42
|
-
# 返回当前值或上一次非零值
|
|
43
|
-
return memory_value if memory_value != 0 else self.last_nonzero_memory
|
|
69
|
+
while self.running:
|
|
70
|
+
line = process.stdout.readline() # 逐行读取
|
|
71
|
+
|
|
72
|
+
if not line: # 进程结束或无输出时退出
|
|
73
|
+
break
|
|
74
|
+
|
|
75
|
+
# 匹配 PID 和内存行 (例如: "12345 123.4M")
|
|
76
|
+
match = re.match(r'^\s*(\d+)\s+([\d,.]+[KMG]?)\s*$', line.strip())
|
|
77
|
+
if match:
|
|
78
|
+
pid = match.group(1)
|
|
79
|
+
mem_str = match.group(2)
|
|
80
|
+
|
|
81
|
+
# 检查是否在监控列表中
|
|
82
|
+
with self.lock:
|
|
83
|
+
if pid in self.pids:
|
|
84
|
+
mem_mb = self._convert_to_mb(mem_str)
|
|
85
|
+
# 直接更新当前数据,不保存历史
|
|
86
|
+
self.current_data[pid] = round(mem_mb, 2)
|
|
87
|
+
|
|
44
88
|
except Exception as e:
|
|
45
|
-
print(e)
|
|
89
|
+
print(f"Monitoring error: {e}")
|
|
46
90
|
finally:
|
|
47
|
-
if
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
91
|
+
if process.poll() is None: # 确保进程终止
|
|
92
|
+
process.terminate()
|
|
93
|
+
|
|
94
|
+
def get_current_data(self):
|
|
95
|
+
"""
|
|
96
|
+
获取当前内存数据(线程安全)
|
|
97
|
+
只返回当前监控的 PID 的最新内存值
|
|
98
|
+
"""
|
|
99
|
+
with self.lock:
|
|
100
|
+
# 只返回当前监控列表中的 PID 数据
|
|
101
|
+
return {
|
|
102
|
+
pid: self.current_data.get(pid, 0.0)
|
|
103
|
+
for pid in self.pids
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
def get_current_json(self):
|
|
107
|
+
"""获取 JSON 格式的当前内存数据"""
|
|
108
|
+
data = self.get_current_data()
|
|
109
|
+
return json.dumps(data, indent=2)
|
|
110
|
+
|
|
111
|
+
def stop(self):
|
|
112
|
+
"""停止监控"""
|
|
113
|
+
self.running = False
|
|
114
|
+
if self.thread and self.thread.is_alive():
|
|
115
|
+
self.thread.join(timeout=1)
|
|
116
|
+
print("Memory monitor stopped")
|
monitor/monitor_pids.py
CHANGED
|
@@ -26,6 +26,7 @@ class PidsPerf:
|
|
|
26
26
|
current_pid = self.processUtil.find_main_process_pid(self.process_name)
|
|
27
27
|
vm = VmMapMemory()
|
|
28
28
|
next_time = time.time() # 初始化下一次执行的时间点
|
|
29
|
+
first_iteration = True # 标志变量,用于跳过第一次循环
|
|
29
30
|
while True:
|
|
30
31
|
start_time = time.time() # 记录循环开始时间
|
|
31
32
|
minor_cpu_sum = 0
|
|
@@ -45,13 +46,19 @@ class PidsPerf:
|
|
|
45
46
|
|
|
46
47
|
gpu_memory_usage, gpu_memory_total, gpu_memory_free = get_gpu_memory()
|
|
47
48
|
# 使用 asyncio.gather 并发获取内存数据
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
vm.update_pids(current_pids)
|
|
50
|
+
|
|
51
|
+
if first_iteration:
|
|
52
|
+
first_iteration = False # 第一次循环后将标志置为 False
|
|
53
|
+
await asyncio.sleep(self.interval / 1000) # 等待一段时间以确保数据稳定
|
|
54
|
+
continue # 跳过第一次循环
|
|
55
|
+
|
|
56
|
+
for process in pids_process:
|
|
51
57
|
try:
|
|
52
58
|
cpu_percent = process.cpu_percent()
|
|
53
59
|
mem_percent = u'%.2f' % (process.memory_percent()) # 内存利用率
|
|
54
|
-
|
|
60
|
+
vm_memory_data = json.loads(vm.get_current_json())
|
|
61
|
+
real_mem = vm_memory_data.get(str(process.pid), 0) # 默认值为 0(如果未找到对应 PID)
|
|
55
62
|
thread_count = process.num_threads() # 线程总数
|
|
56
63
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
57
64
|
cpu_percent = 0
|
|
@@ -3,8 +3,8 @@ monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
3
3
|
monitor/get_process_name.py,sha256=HxePo2gdrTo2Ukg4DTnYzUMdczVWywCeLCXQ-RRWyu8,3913
|
|
4
4
|
monitor/mac_gpu.py,sha256=kQDPMW04lIYPBbJw772Jh1OQxj-D4JNmdjJlP6BuR4w,2320
|
|
5
5
|
monitor/monitor_mac.py,sha256=OoptTTXTZQupzBwgGOfKNjyYAKBxDy-wI3l6T7XVE8s,4651
|
|
6
|
-
monitor/monitor_mac_vmmap.py,sha256=
|
|
7
|
-
monitor/monitor_pids.py,sha256=
|
|
6
|
+
monitor/monitor_mac_vmmap.py,sha256=j_4Gl6uTnOcjbrYVsYfd_TNhhYo0ewUZf-zCpGUeEgs,3751
|
|
7
|
+
monitor/monitor_pids.py,sha256=kIy8oHIN-OwSDqWHTEUlCFpqCdsvGWmX9gtU0cb0W40,17228
|
|
8
8
|
monitor/monitor_win.py,sha256=xs5nzqqEPoDmJTegh3lQhVjjpPcOWnruWKK65ttqnTo,6161
|
|
9
9
|
monitor/run_monitor.py,sha256=HDQXHIx47ZRN4Gp0PTr0yWKVM28n8A7-NaO--_pdgso,1577
|
|
10
10
|
monitor/sys_info.py,sha256=aNultuRoQuRYPkYo397xAXVDXP07Qx5JOHtYzNmEvuc,3208
|
|
@@ -24,8 +24,8 @@ monitor/DLL/sechost.dll,sha256=1mXCrgNDRBiZ2XZk7eTpDm4oPG-x9BW4uYUVkrfvBkk,69986
|
|
|
24
24
|
monitor/DLL/ucrtbased.dll,sha256=vtmKFPEHyr2OXkrUOu3Qs1dlbKG1dxZ8ItKCkTTU5S4,2238056
|
|
25
25
|
monitor/DLL/vcruntime140.dll,sha256=AsaqDm5iRBGp8ZsDYKeGWrFZCOJgJFEOXDipwINiw1o,119888
|
|
26
26
|
monitor/DLL/vcruntime140_1.dll,sha256=fdmqAuJxxoym1fGNZR0joV1yWXFa9DMmV4993ifzdjc,49640
|
|
27
|
-
pmonitor-1.
|
|
28
|
-
pmonitor-1.
|
|
29
|
-
pmonitor-1.
|
|
30
|
-
pmonitor-1.
|
|
31
|
-
pmonitor-1.
|
|
27
|
+
pmonitor-1.5.0.dist-info/METADATA,sha256=BAZnw0kdkSDw4V3MrOBTuSW2Oc090dVpMWOLfNj2Xco,291
|
|
28
|
+
pmonitor-1.5.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
29
|
+
pmonitor-1.5.0.dist-info/entry_points.txt,sha256=vmlLEANgf2fZar9BeXYiKdF6GMJbVXip-SIZx5yPXDo,55
|
|
30
|
+
pmonitor-1.5.0.dist-info/top_level.txt,sha256=tGkQDkVeyKgP5Rr7acpp0df83NBAnI8up0sGwRxuuQ4,8
|
|
31
|
+
pmonitor-1.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|