Конкуренция против параллелизма в многопоточности Python? - PullRequest
0 голосов
/ 09 октября 2019

Резюме:

Не такая большая проблема, просто вопрос о потоке 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]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...