Колко CPU трябва да използва извикването на Python time.sleep(n).

Имам програма, работеща на стар лаптоп, която постоянно следи папка Dropbox за добавяне на нови файлове. Когато работи, Python процесът използва близо 50% от процесора на двуядрена машина и около 12% на 8-ядрена машина, което предполага, че използва близо 100% от едно ядро). Това отделя много топлина.

Съответният бит код е:

while True:
    files = dict ([(f, None) for f in os.listdir(path_to_watch)])
    if len(files) > 0:
        print "You have %s new file/s!" % len(files)
        time.sleep(20)

В случай, че няма нов файл, със сигурност по-голямата част от времето трябва да бъде прекарано в time.sleep() в чакане, което не бих си помислил, че ще натовари процесора - и отговорите тук изглежда казват, че не трябва да е така.

Така че два въпроса:

1) Тъй като time.sleep() не би трябвало да натоварва толкова процесора, какво се случва тук?

2) Има ли друг начин за наблюдение на папка за промени, който би работил по-хладно?


person Jamie Bull    schedule 01.08.2013    source източник
comment
Вашият time.sleep е с твърде голям отстъп, поставете го в главния блок while True, това гарантира, че винаги ще работи.   -  person Wessie    schedule 01.08.2013


Отговори (2)


1) Вашият сън се извиква само когато има нови файлове.

Това трябва да е много по-добре:

while True:
    files = dict ([(f, None) for f in os.listdir(path_to_watch)])
    if len(files) > 0:
        print "You have %s new file/s!" % len(files)
    time.sleep(20)

2) Да, особено ако използвате Linux. Gamin би бил нещо, което бих препоръчал да разгледате.

Пример:

import gamin
import time
mydir = /path/to/watch
def callback(path, event):
    global mydir
    try:
        if event == gamin.GAMCreated:
            print "New file detected: %s" % (path)
            fullname = mydir + "/" + path
            print "Goint to read",fullname
            data = open(fullname).read()
            print "Going to upload",fullname
            rez = upload_file(data,path)
            print "Response from uploading was",rez
    except Exception,e: #Not good practice
        print e
        import pdb
        pdb.set_trace()


mon = gamin.WatchMonitor()
mon.watch_directory(mydir, callback)
time.sleep(1)
while True:
    ret = mon.handle_one_event()
mon.stop_watch(mydir)
del mon
person Foon    schedule 01.08.2013
comment
Уау, ударен момент относно проблема с отстъпа! И аз ще погледна gamin, въпреки че в момента съм на Windows. - person Jamie Bull; 01.08.2013
comment
99% съм сигурен, че има еквивалент на Windows чрез Windows API, въпреки че може да се наложи да използвате IronPython. От друга страна, разбрах, след като публикувах, истинската полза за gamin и т.н. е, че получавате по същество незабавни актуализации; ако основната ви грижа е просто да накарате процесора да не изгори, вашият модел на запитване със заспиване има много по-голям смисъл да го поддържате просто. (И всички сме били там с удара по главата, въпреки че теоретично Python трябва да бъде по-лесен за забелязване... Все още си спомням C програма, в която имах висящ else, който изглеждаше добре с отстъпите, които имах) - person Foon; 01.08.2013
comment
Проблемът е, че частта, която публикувах, всъщност беше правилна. Това дава шанс на новия файл/и да се синхронизира в Dropbox. Real time.sleep() беше по-надолу и не беше (съвсем) толкова лесен за забелязване, но все пак беше с неправилен отстъп. - person Jamie Bull; 01.08.2013

Съществува и междуплатформен API за наблюдение на промените във файловата система: Watchdog

person Rahul K    schedule 01.08.2013