Резюме:
Не такая большая проблема, просто вопрос о потоке Python. Насколько я понимаю, потоки Python не могут обрабатываться параллельно из-за GIL, и все потоки работают одновременно на одном и том же ядре ЦП. Я хотел посмотреть, не стала ли написанная мною многопоточная программа ввода-вывода привязываться к процессору, поэтому я написал некоторый код для проверки этого, однако получил некоторые результаты, которые не соответствуют моему пониманию потоков Python. Кажется, что когда я начинаю многопоточность, это увеличивает использование памяти ЦП всеми ядрами, что противоречило тому, что я ожидал. Означает ли это, что CPU1, например, выгружает некоторые другие фоновые задачи на другие ядра, поскольку он имеет повышенную нагрузку от многопоточной программы, или есть некоторый параллелизм в многопоточности, о котором я не знал? или модуль psutils не подходит для этого анализа, и у меня неточные данные?
У меня есть многопоточная программа для загрузки множества различных файлов, в которых потоки будут порождать подпотоки. Код программы не очень важен, поэтому я приведу код, который я использовал для мониторинга использования памяти ЦП на ядро.
Вы запускаете поток монитора перед запуском потоков основных программ. Входными данными являются threading.Event () (для уничтожения потока монитора) и max_time для тайм-аутов. Я также показал, как вызывать его в классе Example_thread.
from threading import Thread
import psutil
import matplotlib.pyplot as plt
import psutil
class Example_thread(Thread):
def __init__(self):
super().__init__()
def run(self):
mon_event=threading.Event()
mon=monitor(mon_event,(exp_time + 12))
mon.start()
"""
Insert desired code
"""
mem_usage={}
mon_event.set()
mem_usage=mon.evaluate()
return(mem_usage)
class monitor(Thread):
def __init__(self,event,max_time):
super().__init__()
self.event=event
self.mem_usage_dict={}
self.initial=time.time()
self.max_time=max_time
self.mem_usage_dict={'time':[],'CPU1':[],'CPU2':[],'CPU3':[],'CPU4':[]}
def run(self):
while not self.event.isSet():
ls=(psutil.cpu_percent(percpu=True))
self.point=time.time()
self.mem_usage_dict['CPU1'].append(ls[0])
self.mem_usage_dict['CPU2'].append(ls[1])
self.mem_usage_dict['CPU3'].append(ls[2])
self.mem_usage_dict['CPU4'].append(ls[3])
self.mem_usage_dict['time'].append(self.point-self.initial)
if (self.point-self.initial)>self.max_time:
break
time.sleep(7)
print('Finished monitor')
def evaluate(self):
print(self.mem_usage_dict)
#can plot here if needed...
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
for key in self.mem_usage_dict.keys():
if key != 'time':
ax.plot(self.mem_usage_dict['time'],self.mem_usage_dict[key],label=key)
ax.legend()
fig.show()
return (self.mem_usage_dict)
Я ожидал увидеть только использование памяти для CPU1 (т.е. ядра 1), поскольку потоки должны работать только одновременно, но вместо этого я увиделвсе ядра увеличиваются. На графике ниже ось X - это время, а ось Y - использование памяти ЦП в процентах, а CPU1-4 - каждое из ядер.
! [Plot] [1] [1]