LINUX.ORG.RU

while true жрет 100% процессора

 


0

2

вот такой код

  while True:            
            if datetime.now().time() == pList[1]:
                pList = do_callback()  #почти никогда не выполняется
            
            if self.status == 'waitstop':
                self.__lock.acquire()
                self.status = 'ready'
                self.__lock.release()
                log.info('Stopping called')
                break
загружает проц на 100%, хотя 99% времени он ничего не делает

можно ли как-либо снизить использование процессора? спасибо, python только осваиваю.

★★★★
Ответ на: комментарий от vahtu

ну а это тут при чем? это часть блока if, который выполняется, только когда вызван stop из родительского потока //да, можно вызывать stop из класса thread, но это не потокобезопасно.

pashazz ★★★★
() автор топика
Ответ на: комментарий от pashazz

Я не знаю! Но у любого (нормального) языка есть profiler.

vahtu
()

while(true) всегда жрет 100% процессора. Нужно или на короткое время засыпать, или просто time.sleep(0).

note173 ★★★★★
()

В приведенном коде нет никакого ожидания, что что-то изменилось. Следует использовать какой-либо механизм синхронизации, например, condition variable, для того, чтобы нить с циклом могла заснуть до тех пор, пока выполнится одно из условий («datetime.now().time() == pList[1]» или «self.status == 'waitstop'»).

dmitry_vk ★★★
()

загружает проц на 100%, хотя 99% времени он ничего не делает

99% времени он ничего не делает

Мальчик, ты дурак?

tailgunner ★★★★★
()

хотя 99% времени он ничего не делает

Кстати, как уже заметили, 99% времени процессор усердно занят проверкой условия. Это называется spinlock и в питоне не имеет смысла.

dmitry_vk ★★★
()

Купи новый проц, нищеброд; а то даже банальный `while true` не тянет.

anonymous
()
Ответ на: комментарий от buddhist

То есть как это?

То есть, цикл гоняется вхолостую со всей скоростью, позволенной процессором. Казалось бы, при чём тут нагрузка в 100%?

jessey
()

Хинт:

with self.__lock:
    self.status = 'ready'

Ну а вообще, судя по коду, ты замыслил что-то страшное и неправильное.

true_admin ★★★★★
()

Типичная ситуация, некоторым даже пофигу на неё - в DOS все циклы именно так и делались. Сейчас уже некошерно, т.к. расходует батарею (если есть), затормаживает полезные задачи на фоне и, как ни странно, сам процесс становится менее отзывчив - ядро жадные процессы не очень уважает и рано или поздно всё равно отберёт квант времени и отдаст остальным, но в случае while true квант закончится очень невовремя.

Типичное решение - сделать sleep на константный интервал времени. Проблема в том, что возникает задержка отзыва программы, когда событие таки произошло - даже sleep(20ms) уже некрасив в интерактивщине. Но в данном случае нужно именно ждать определённого времени, так можно просто взять и вычислить оставшееся время и сделать nanosleep на этот интервал. Фишка nanosleep в том, что если придёт сигнал, то программа очнётся раньше установленного времени, а оставшееся время будет записано во второй параметр. Поэтому условие if self.status == 'waitstop': можно реализовать посылкой сигнала.

nanosleep - сишная функция, я не знаю, есть ли в python аналоги, да ещё и кроссплатформенные (биндинг-то есть в любом случае). Надеюсь, подскажут.

anonymous
()
Ответ на: комментарий от true_admin

Ну а вообще, судя по коду, ты замыслил что-то страшное и неправильное

Самый верный комментарий в этом треде.

pevzi ★★★★★
()

while true жрет 100% процессора

и что?

можно ли как-либо снизить использование процессора?

man sleep

drBatty ★★
()

Он 99% времени занят прогонкой пустого цикла. Ещё бы не жрал.

Artificial_Thought ★★★★
()

кстати, в C есть wait(2), а в этом вашем пайтоне разве нет чего-то такого?

drBatty ★★
()
Ответ на: комментарий от anonymous

Типичная ситуация, некоторым даже пофигу на неё - в DOS все циклы именно так и делались. Сейчас уже некошерно, т.к. расходует батарею (если есть)

уважаемый школьник, не порите чушь, а учите матчасть. Батарея тут не причём. Есть в CPU команда HLT, которая как раз и нужна для остановки CPU. И она позволяет обойтись без таких бесконечных циклов.

drBatty ★★
()
Ответ на: комментарий от drBatty

Т.е. вы, мой юный друг, утверждаете, что в DOS в большинстве программ циклы делались не через while (true) или ассемблерные бесконечные циклы?

anonymous
()
Ответ на: комментарий от pashazz

а так спасибо, расставил слипы, все кошерно. На самом деле я еще вчера до этого допер,еще до iSlava, но как-то хотелось посмотреть на дискуссию.

pashazz ★★★★
() автор топика

busy wait загружает проц на 100%. А что, собственно говоря, в этом удивительного?

Чем мощнее проц, тем больше тормоза при использовании таких конструкций, ЯП значения не имеет

annulen ★★★★★
()
Ответ на: комментарий от anonymous

Т.е. вы, мой юный друг, утверждаете, что в DOS в большинстве программ циклы делались не через while (true) или ассемблерные бесконечные циклы?

нет. большинство действительно грузило на 100%, но это не есть хорошо. Процессор - это большой и сложный чип, и если он греется, это плохо. Срок службы любого чипа экспоненциально падает с ростом температуры, потому намного лучше, если процессор холодный, даже во времена DOS. И тем не менее, вика пишет:

All x86 processors from the 8086 onwards had the HLT instruction, but it was not used by MS-DOS[2] and was not specifically designed to reduce power consumption until the release of the Intel DX4 processor in 1994.[3] Some of the first 100MHz DX chips had a buggy HLT state, prompting the developers of Linux to implement a «no-hlt» option for use when running on those chips[4] but this was fixed in later chips.

drBatty ★★
()
Ответ на: комментарий от ymuv

Вообще-то он вроде правильно сказал. Большинство запущенных дос-программ грузят ядро на 100%

а большинство сайтов написано быдлокодерами на пхп. Это разве хорошо?

drBatty ★★
()

sleep() - это обход проблемы, а подходящее решение предложил kernelpanic.

gag ★★★★★
()

Результаты профилирования в студию кто-нибудь выложит?

vahtu
()
Ответ на: комментарий от true_admin

ну а что вы хотели? Убунта дает 3 недели. Притом я же не могу заниматься этим все время => на проектировку нет времени.

pashazz ★★★★
() автор топика
Ответ на: комментарий от pashazz

Убунта дает 3 недели

?? это как?

на проектировку нет времени.

а это самая большая ошибка какую можно совершить. Архитектура это самое главное. Просто поверь мне на слово, когда будешь делать рефакторинг и переписывание поймёшь. Да и не так уж много времени на проектирование уходит. Гораздо больше уходит на перепроектирование :)

true_admin ★★★★★
()
Ответ на: комментарий от drBatty

Срок службы любого чипа экспоненциально падает с ростом температуры

ни одного дохлого проца я не видел, хотя в дц работал и менял кулера у перегревающихся тачек

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

У меня есть один дохлый целерон-prescott с симптомами скурвившегося термоинтерфейса между корпусом и кристаллом (греется и выключается при исправном охлаждении с оверкиллом за минуты 2 от холодного старта).

x3al ★★★★★
()
Ответ на: комментарий от true_admin

Да и не так уж много времени на проектирование уходит. Гораздо больше уходит на перепроектирование :)

Быстрый выпуск работающего нормально продукта, который к концу разработки уперся в свою архитектуру и оброс спагетти-кодом, и который к следующей версии надо переписать с нуля, иногда все же лучше долгого проектирования. При проектировании все равно не учесть всего.

note173 ★★★★★
()
Ответ на: комментарий от true_admin

showdown был последние 3 недели, они там ноутбуки раздают.

pashazz ★★★★
() автор топика
Ответ на: комментарий от true_admin

и потом, я думаю, это нормальная архитектура. GUI фронтенд из другого потока изменяет свойство status на принудительное завершение, я это проверяю, завершаюсь.

Как иначе сигналить потоку из заранее неизвестного места, кроме как через глобальную переменную, я не знаю.

pashazz ★★★★
() автор топика
Ответ на: комментарий от pashazz

попробовал condition, результаты меня очень удивили:

'''
Created on 09.07.2012

@author: pasha
'''
import threading, random

cond = threading.Condition()

def pred():
    print ('pred() called')
    return random.choice((True, False))

def work():
    with cond:
        print ('wait_for()')
        cond.wait_for(pred)

def cli():
    t = threading.Thread(target=work)
    t.start()
    t.join()
    print ('work() done')
    

if __name__ == '__main__':
    cli()


В 50% случаев это завершается сразу (правильно), но когда random выбирает False, wait_for() и не думает снова вызывать pred() т.е. выводится
wait_for()
pred() called

и все... хоть час жди.

pashazz ★★★★
() автор топика
Ответ на: комментарий от true_admin

ни одного дохлого проца я не видел, хотя в дц работал и менял кулера у перегревающихся тачек

ну при нормальной температуре градусов 30..60 средний срок службы составляет десятки лет (если не больше), т.ч. не удивительно. Но процессоры иногда таки дохнут, я с таким встречался. Помниться видел Cel2000 (или типа того, без разгона), который проработал около года с заклинившим вентилятором. Но таки сдох. Пришлось заменить CPU + ближайшую к нему планку RAM. Температура там была наверное градусов 80 у CPU, и эта планка тоже была ощутимо горячей. (проц умер полностью, но память была полудохлая, венда иногда висла и testram давал только несколько проходов без ошибок)

drBatty ★★
()
Ответ на: комментарий от dave

Ты писал программы под ДОС?

да, но обычно такие подробности не нужны. Есть ведь стандартные функции. Даже в DOS они были. Читать/писать можно было прерываниями BIOS, ЕМНИП клава тоже могла прервать HLT вызвав свой обработчик. Т.ч. бесконечные циклы и sleep уже тогда были не нужны.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.