Канонический / стандартный способ ограничения потоков в python - PullRequest
2 голосов
/ 13 февраля 2011

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

ncpus = detectCPUs()

for (dirpath, dirnames, filenames) in os.walk(path_to_root):
    for filename in filenames:
        while True:
            if threading.activeCount() < ncpus - 1:
                MyThread(dirpath, filename).start()
                break
            else:
                time.sleep(100)

Я не могу избавиться от ощущения, что в библиотеке threading есть функцииили в другом месте Python, который автоматически сделал бы это для меня без необходимости следить за количеством потоков и процессоров.Кто-нибудь знает что-нибудь?Или указав, как опытные ветераны это сделают?

Некоторые ограничения.На общих машинах, которые я использую, установлен только Python 2.5, и у меня нет прав root для установки.Так что о multiprocessing или о хороших библиотеках, требующих Python 2.6 или выше, не может быть и речи.

Ответы [ 3 ]

2 голосов
/ 13 февраля 2011

Даже если вы не можете обновить Python, вы все равно можете использовать многопроцессорность.

multiprocessing - это задний порт пакета Python 2.6 / 3.0 multiprocessing,[…] Этот автономный вариант предназначен для совместимости с Python 2.4 и 2.5 и будет извлекать исправления / улучшения из python-trunk.

Просто установите его как локальную библиотеку.

Существует несколько других библиотек «пул рабочих / потоков», но вы действительно хотите использовать многопроцессорность или хотя бы подпроцесс.GIL в Python означает, что «потоки» часто блокируют друг друга на одном процессоре, снижая пропускную способность и медленнее, чем если бы процесс был однопоточным, особенно когда задействован ввод / вывод.

2 голосов
/ 13 февраля 2011

Возможно, вам нужна реализация пула потоков?

http://code.activestate.com/recipes/577187/

Это будет выглядеть примерно так:

pool = ThreadPool(num_threads)
for obj in objects:
    pool.add_task(obj.do_stuff, [arg1, arg2])
pool.wait_completion()    
0 голосов
/ 13 февраля 2011

Если вы используете канонический питон, то существует ограничение на полезность потоков. Канонический питон использует глобальную блокировку интерпретатора (GIL), которая позволяет одновременно выполнять только один поток питона.

Однако, если ваша файловая операция блокируется на длительные периоды времени или вы используете библиотеку python, написанную на C, которая выпускает GIL, то потоки помогут вам.

Я бы настоятельно рекомендовал взглянуть на многопроцессорность, поскольку это позволит вам обойти GIL.

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