注意:我想在不使用任何框架的情况下实现这一点。
我必须使用python创建一个Web应用程序。应用程序应在过去60秒内保持每个进程的CPU使用率的运行平均值。它应该充当Web服务器,并且在收到请求时,应该返回每个进程的当前平均值。以下是我编写的脚本。record_usage.py是我想在server.py运行时立即运行的脚本。这样它将运行并维护cpu使用情况数据,我打算在收到XHR请求并将其发送回客户端时读取该数据。
因此,我的问题是如何调用此要求?我试图运行record_usage.py使用subprocess.POPEN启动服务器后。record_usage.py也开始在后台运行。但是,当我尝试访问由它创建的数据时,我创建的类对象不是它使用的对象,而是一个新的对象。如何完成此链接?
请问我不清楚的事情。
server.py中的最新更改
if __name__ == '__main__':
RU_OBJ = RU(settings.SAMPLING_FREQ, settings.AVG_INTERVAL)
RU_LOCK = RLock()
# Record CPU usage in a thread.
ru_thread = Thread(target=RU_OBJ.record, args=(RU_LOCK,))
ru_thread.daemon = True
ru_thread.start()
# Run server.
run()
record_usage.py中的最新更改
def record(self, lock):
while True:
with lock:
self.add_processes()
time.sleep(self.sampling_freq)
这是应用锁的正确方法吗?在读取过程信息时,将应用类似的锁定。能行吗?
添加了功能:
def add_processes(self,):
for _process in psutil.process_iter():
try:
new_proc = _process.as_dict(attrs=['cpu_times', 'name', 'pid',
'status'])
except psutil.NoSuchProcess:
continue
pid, (user, _sys) = new_proc['pid'], new_proc.pop('cpu_times')
# Get or create details object for the process.
existing = self.processes.setdefault(pid, new_proc)
# Get or create queue object for the CPU times of the process.
queue_dict = self.process_queue.setdefault(pid, dict())
# User CPU time.
user_q = queue_dict.setdefault('user_q', PekableQueue(self.avg_interval))
user_q.enqueue(user)
user_avg = get_avg(user_q)
# System CPU time.
sys_q = queue_dict.setdefault('sys_q', PekableQueue(self.avg_interval))
sys_q.enqueue(_sys)
sys_avg = get_avg(sys_q)
# Update the details object for the process.
existing.update(user_avg=user_avg, sys_avg=sys_avg, **new_proc)
def get_curr_processes(self):
return [self.processes[pid] for pid in psutil.get_pid_list()
if pid in self.processes]
要在另一个线程中收集统计信息:
if __name__ == '__main__':
from threading import Thread, Lock
import record_usage
lock = Lock()
t = Thread(target=record_usage.record, args=[lock])
t.daemon = True
t.start()
run(lock)
如果您在一个线程中更改了一些共享数据并在另一个线程中进行了读取,则可以使用锁保护访问/更改值的位置:
#...
with self.lock:
existing = self.processes.setdefault(pid, new_proc)
#...
with self.lock:
existing.update(user_avg=user_avg, sys_avg=sys_avg, **new_proc)
#...
def get_curr_processes(self):
with self.lock:
return [self.processes[pid] for pid in psutil.get_pid_list()
if pid in self.processes]
self.lock
所有线程中的同一对象至关重要。如果self.processes
为a,dict
则无需在CPython中使用锁。这些方法是用C实现的,并且解释器在调用它们时不会释放GIL(全局锁),即,一次只能访问一个线程dict
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句