Завершить несколько потоков, когда какой-либо поток завершает задачу
Я новичок как для python, так и для потоков. Я написал код python, который работает как искатель веб-страниц и ищет сайты для определенного ключевого слова. Мой вопрос в том, как я могу использовать потоки для одновременного запуска трех разных экземпляров моего класса. Когда один из экземпляров находит ключевое слово, все три должны закрывать и останавливать сканирование в Интернете. Вот какой код.
class Crawler: def __init__(self): # the actual code for finding the keyword def main(): Crawl = Crawler() if __name__ == "__main__": main()
Как я могу использовать потоки, чтобы Crawler выполнял три разных обхода одновременно?
- Глобальная переменная Python с потоком
- Заполнение Python3 с помощью uWSGI
- Стратегия программирования, чтобы обойти ограничение потока os?
- wxPython: Threading GUI -> Использование специального обработчика событий
- Почему я получаю TypeError в Threading в Python
- Ограничить количество потоков в numpy
- Продолжайте работу tkinter Progressbar до создания файла
- Когда я запускаю, это говорит мне об этом: NameError: имя «lock» не определено?
- Есть ли у Python аналогичный механизм управления для CountDownLatch для Java?
- Python: каков правильный способ передачи аргументов в threading.Thread instance
5 Solutions collect form web for “Завершить несколько потоков, когда какой-либо поток завершает задачу”
Кажется, что нет (простой) способ прервать поток в Python.
Ниже приведен простой пример одновременного запуска нескольких HTTP-запросов:
import threading def crawl(): import urllib2 data = urllib2.urlopen("http://www.google.com/").read() print "Read google.com" threads = [] for n in range(10): thread = threading.Thread(target=crawl) thread.start() threads.append(thread) # to wait until all three functions are finished print "Waiting..." for thread in threads: thread.join() print "Complete."
С дополнительными накладными расходами вы можете использовать многопроцессорный aproach, который является более мощным и позволяет прекратить поточно-подобные процессы.
Я использовал этот пример. Надеюсь, это будет полезно для вас:
import multiprocessing def crawl(result_queue): import urllib2 data = urllib2.urlopen("http://news.ycombinator.com/").read() print "Requested..." if "result found (for example)": result_queue.put("result!") print "Read site." processs = [] result_queue = multiprocessing.Queue() for n in range(4): # start 4 processes crawling for the result process = multiprocessing.Process(target=crawl, args=[result_queue]) process.start() processs.append(process) print "Waiting for result..." result = result_queue.get() # waits until any of the proccess have `.put()` a result for process in processs: # then kill them all off process.terminate() print "Got result:", result
Начать поток легко:
thread = threading.Thread(function_to_call_inside_thread) thread.start()
Создайте объект события, чтобы сообщить, когда вы закончите:
event = threading.Event() event.wait() # call this in the main thread to wait for the event event.set() # call this in a thread when you are ready to stop
После того, как событие было запущено, вам нужно добавить методы stop () для ваших сканеров.
for crawler in crawlers: crawler.stop()
А затем вызовите соединение по потокам
thread.join() # waits for the thread to finish
Если вы выполняете какой-либо объем такого программирования, вам нужно посмотреть на модуль eventlet. Он позволяет писать «резьбовой» код без многих недостатков потоковой передачи.
Прежде всего, если вы новичок в python, я бы не стал рекомендовать сталкиваться с проблемами. Привыкайте к языку, затем займите многопоточность .
С учетом сказанного, если ваша цель состоит в том, чтобы распараллелить (вы сказали, что «запустить одновременно»), вы должны знать, что в python (или, по крайней мере, в реализации по умолчанию, CPython) несколько потоков НЕ будут выполняться параллельно, даже если доступно несколько процессорных ядер . Прочтите на GIL (Global Interpreter Lock) для получения дополнительной информации.
Наконец, если вы все еще хотите продолжить, проверьте документацию Python для модуля потоковой передачи. Я бы сказал, что документы Python так же хороши, как и ссылки, с большим количеством примеров и объяснений.
Для этой проблемы вы можете использовать либо модуль потоковой передачи (который, как говорили другие, не будет выполнять поточную передачу из-за GIL), либо модуль многопроцессорности (в зависимости от того, какую версию Python вы используете). У них очень похожие API, но я рекомендую многопроцессорность, поскольку это больше Pythonic, и я считаю, что общение между процессами с Pipes довольно просто.
Вы хотите иметь свой основной цикл, который будет создавать ваши процессы, и каждый из этих процессов должен запускать ваш искатель, чтобы он возвращался к основному потоку. Ваш процесс должен прослушивать сообщение на трубке, выполнять обход и отправлять сообщение по каналу, если он что-то находит (перед завершением). Ваш основной цикл должен пересекать каждую из труб обратно, слушая это сообщение «нашел что-то». Как только он услышит это сообщение, он должен отправить его по каналам в оставшиеся процессы, а затем дождаться их завершения.
Более подробную информацию можно найти здесь: http://docs.python.org/library/multiprocessing.html
Прежде всего, потоки не являются решением в Python. Из-за GIL Threads работает не параллельно. Таким образом, вы можете справиться с этим с многопроцессорной обработкой, и вы будете ограничены количеством процессорных ядер.
Какова цель вашей работы? Вы хотите иметь сканера? Или у вас есть некоторые академические цели (изучение потоков и Python и т. Д.)?
Еще один момент: Crawl тратить больше ресурсов, чем другие программы, так что же вы продаете?
- Почему Python 3 не поддерживает обратную совместимость?
- Класс Django: как передать дополнительные параметры методу as_view?