Вопрос, собственно, состоит в том, как получить информацию из потока. Есть консольная программа, выполняющая копирование файлов по сети. В силу потребностей, она была доработана и задачи запускаются в потоках. Вот, собственно, и требуется получить информацию о статусе выполнения программы в потоке. Может кто делал что подобное или работал с потоками?
3 ответа
Для обмена информацией между потоками можно использовать очереди. Вот документация к ним. В конце есть пример для работы с потоками. Вот отличная книга по программированию на Python. В частности там есть много примеров по многопоточности.Либо книга Бизли Подробный справочник по Python гл. 20. Та же документация только на русском в виде книги.
-
А есть хорошие примеры на русском? Я читал документацию, но не могу разобраться 3 апр 2013 в 7:59
Чтобы скопировать сетевые файлы из списка filenames
по 20 файлов одновременно, можно использовать ThreadPool и докладывать о текущем прогрессе в основном потоке:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from multiprocessing.pool import ThreadPool
def copy_file_over_network(filename):
try:
# copy file here
...
except Exception as e: # error
return filename, str(e)
else: # success
return filename, None
pool = ThreadPool(20) # copy 20 files at a time
total = float(len(filenames))
it = pool.imap_unordered(copy_file_over_network, filenames)
for i, (filename, error) in enumerate(it, start=1):
if error is None:
print(u"Скопировал {:%} {}".format(i/total, filename))
else:
print(u"Не смог скопировать {:!r}: {}".format(filename, error))
Питон отпускает GIL во время операций по вводу/выводу т.е., файлы могут действительно копироваться параллельно: производительность скорее всего ограничивается только скоростью диска или пропускной способностью (или задержкой) сети.
В статье пишут:
Питоновская реализация многопоточности ограниченная. Интерпретатор питона использует внутренний глобальный блокировщик (GIL), который позволяет выполняться только одному потоку. Это сводит на нет преимущества многоядерной архитектуры процессоров. Для многопоточных приложений, которые работают в основном на дисковые операции чтения/записи, это не имеет особого значения, а для приложений, которые делят процессорное время между потоками, это является серьезным ограничением.
Вам все еще хочется использовать потоки?
-
1
-
1@avp, так ведь ТС как раз и использует дисковые операции. Так что для него выгода явно есть. К тому же - разве до некоторого времени (или до сих пор?) многозадачность не была липовой? "Липовая" - т.к. в единицу времени выполнялся только один процесс, остальные ждали когда очередь до них дойдет. Насколько понял питон предоставляет аналогичный функционал.– BOPOH3 апр 2013 в 11:33
-
@avp, GIL - бяка и свинья гадостная. Самая мерзкая вещь в питоне (и, пожалуй, единственная). Но если цель создания потоков - обеспечение независимости выполняемого кода, а не распределенные вычисления, то большой проблемы это не составляет.– skegg3 апр 2013 в 11:48
-
@mikillskegg, и обычных-то posix threads лучше избегать, а уж в скриптовой реализации... IMHO лучше разделить работу на независимые процессы (fork()) и обмениваться результатами по пайпу.– avp3 апр 2013 в 12:02
-