2013-02-27 2 views
0

Я пишу в основном сканер портов (не совсем, но это близко). Пинг-машины по очереди медленны, поэтому мне определенно нужна какая-то параллельная обработка. Шея бутылки определенно является сетевым вводом-выводом, поэтому я думал, что потоки будут достаточными (с существующим GIL-файлом python), они проще в использовании. Но вместо этого использование процессов приведет к значительному увеличению производительности (15% +)?нити или процессы

К сожалению, у меня нет времени, чтобы попробовать оба подхода и выбрать лучший из них основаны на некоторых измерениях или что-то:/

Спасибо :)

+0

Вы можете использовать параллельную библиотеку, Gevent, Greenlet, Twisted ... Здесь есть список связок http://wiki.python.org/moin/Concurrency/ – Justin

+0

Если у вас есть время задать вопрос о SO и ждать ответа, у вас есть время попробовать в обоих направлениях. Для перехода от, например, 'concurrent.futures.ThreadPoolExecutor' к' concurrent.futures.ProcessPoolExecutor', и, возможно, 30 секунд для записи тестового жгута производительности потребуется около 5 секунд. – abarnert

+0

эти «пул» для меня действительно не подходят, мне нужен больше контроля над отдельными аргументами потоков/процессов, которые они предлагают:/В противном случае это будет кусок торта :) – Paladin

ответ

2

Если у вас нет времени ждать теста производительности, вы, вероятно, просто хотите догадки. Итак:

Возможно, нет никакого реального преимущества для multiprocessing по сравнению с threading здесь.

Существует недостаток multiprocessing в служебных целях. Вы можете обойти это, настроив размер партии, но с threading вам не обязательно.

Итак, я бы использовал резьбу.

Однако я бы сделал это с использованием concurrent.futures.ThreadPoolExecutor, поэтому, когда вы получите немного времени позже, вы можете попробовать однострочное изменение до ProcessPoolExecutor и сравнить производительность.

+0

эти «пул» вещи для меня действительно не подходят, мне нужно больше контролировать отдельные потоки/процессы, а затем они предлагают:/Но спасибо за мнение, я пойду с нитками и увижу :) – Paladin

0

Вообще говоря, вы хотите multiprocessing модуль принять преимущества дополнительных процессорных ядер при обработке. Поскольку каждый процесс получает свой собственный GIL, они могут совершать интенсивные вызовы с ЦП независимо от того, блокирует ли какой-либо конкретный вызов GIL свою продолжительность.

С точки зрения программирования основной недостаток заключается в том, что у вас гораздо меньше разделяемой памяти. Фактически, вы можете отправлять данные только с использованием общих объектов, например multiprocessing.Array или multiprocessing.Value. И поскольку так мало памяти разделяется, каждый раз, когда вы создаете другой экземпляр, вы удваиваете объем памяти.

Резьба может быть работоспособным вариантом, хотя если вы хотите максимальной эффективности, вы должны пойти с асинхронным подходом. Существует ряд инфраструктур для асинхронных сетевых операций ввода-вывода, хотя наиболее известным является, вероятно, Twisted.

+2

Он утверждает, что его код полностью связан с сетью. Поэтому ему не нужно использовать дополнительные ядра процессора. – abarnert

1

Я понял, что я просто опубликую это как потенциальный ответ.
Я использовал, как и Gevent, но другой lib тоже работал.

Это взято с сайта GEvent в

import gevent 
from gevent import socket 
urls = ['www.google.com', 'www.example.com', 'www.python.org'] 
jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls] 
gevent.joinall(jobs, timeout=2) 
[job.value for job in jobs] 

['74 .125.79.106' , '208.77.188.166', '82] .94.164.162'

Это даст вам одновременно подход, без накладных расходов на потоки/процессы =)

Смежные вопросы