Прерывания клавиатуры с многопроцессорным Пулом Python

Если Вы готовы расстаться с небольшим количеством денег, JNIWrapper является полезной библиотекой с Winpack, Вы сможете получить события файловой системы на определенных файлах. К сожалению, окна только.

См. https://www.teamdev.com/jniwrapper.

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

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

125
задан Fragsworth 10 September 2009 в 23:59
поделиться

4 ответа

This is a Python bug. When waiting for a condition in threading.Condition.wait(), KeyboardInterrupt is never sent. Repro:

import threading
cond = threading.Condition(threading.Lock())
cond.acquire()
cond.wait(None)
print "done"

The KeyboardInterrupt exception won't be delivered until wait() returns, and it never returns, so the interrupt never happens. KeyboardInterrupt should almost certainly interrupt a condition wait.

Note that this doesn't happen if a timeout is specified; cond.wait(1) will receive the interrupt immediately. So, a workaround is to specify a timeout. To do that, replace

    results = pool.map(slowly_square, range(40))

with

    results = pool.map_async(slowly_square, range(40)).get(9999999)

or similar.

133
ответ дан 24 November 2019 в 01:00
поделиться

Strangely enough it looks like you have to handle the KeyboardInterrupt in the children as well. I would have expected this to work as written... try changing slowly_square to:

def slowly_square(i):
    try:
        sleep(1)
        return i * i
    except KeyboardInterrupt:
        print 'You EVIL bastard!'
        return 0

That should work as you expected.

-4
ответ дан 24 November 2019 в 01:00
поделиться

По некоторым причинам обрабатываются только исключения, унаследованные от базового класса Exception как обычно. В качестве обходного пути вы можете повторно вызвать KeyboardInterrupt как экземпляр Exception :

from multiprocessing import Pool
import time

class KeyboardInterruptError(Exception): pass

def f(x):
    try:
        time.sleep(x)
        return x
    except KeyboardInterrupt:
        raise KeyboardInterruptError()

def main():
    p = Pool(processes=4)
    try:
        print 'starting the pool map'
        print p.map(f, range(10))
        p.close()
        print 'pool map complete'
    except KeyboardInterrupt:
        print 'got ^C while pool mapping, terminating the pool'
        p.terminate()
        print 'pool is terminated'
    except Exception, e:
        print 'got exception: %r, terminating the pool' % (e,)
        p.terminate()
        print 'pool is terminated'
    finally:
        print 'joining pool processes'
        p.join()
        print 'join complete'
    print 'the end'

if __name__ == '__main__':
    main()

Обычно вы получите следующий результат:

staring the pool map
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
pool map complete
joining pool processes
join complete
the end

Итак, если вы нажмете ^ C , вы получите:

staring the pool map
got ^C while pool mapping, terminating the pool
pool is terminated
joining pool processes
join complete
the end
29
ответ дан 24 November 2019 в 01:00
поделиться

Я обнаружил, что на данный момент лучшим решением будет не использовать функцию multiprocessing.pool, а использовать собственные функции пула. Я предоставил пример, демонстрирующий ошибку с apply_async, а также пример, показывающий, как вообще избежать использования функций пула.

http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/

4
ответ дан 24 November 2019 в 01:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: