Можно ли запустить следующие веб-запросы в параллель?
Я использую Python с пакетом modbus_tk для опроса n
ПЛК. Каждый опрос занимает ~5 секунд. Можно ли запустить их параллельно, чтобы не потребовалось n*5
секунд, чтобы вернуть все данные?
Мой текущий код:
for ip in ip_addresses:
master = modbus_tcp.TcpMaster(host=ip_address)
my_vals = (master.execute(1, cst.READ_HOLDING_REGISTERS, starting_address=15))
return my_vals
2 ответа
У меня нет знаний о modbus_tk, но вы можете просто использовать библиотеку потоков? Создайте 1 поток для каждого IP-адреса для опроса.
Вот пример кода, который должен помочь вам:
import threading
class Poller( threading.Thread ):
def __init__( self, ipaddress ):
self.ipaddress = ipaddress
self.my_vals = None
threading.Thread.__init__(self)
def run( self ):
master = modbus_tcp.TcpMaster(host=self.ipaddress)
self.my_vals = (master.execute(1, cst.READ_HOLDING_REGISTERS, starting_address=15))
pollers = []
for ip in ip_addresses:
thread = Poller(ip)
pollers.append(thread)
thread.start()
# wait for all threads to finish, and collect your values
retrieved_vals = []
for thread in pollers:
thread.join()
retrieved_vals.append(thread.my_vals)
# retrieved_vals now contains all of your poll results
for val in retrieved_vals:
print val
Многопроцессорная обработка также будет работать и здесь, хотя это излишняя проблема. Поскольку это операция ввода / вывода, это идеальный кандидат для многопоточности. GIL (глобальная блокировка интерпретатора) не замедлит вас или что-то еще, а потоки будут иметь меньший вес, чем процессы.
Используйте multiprocessing.imap_unordered. Он позволяет запускать пул процессов, отправлять задания в пул и получать результаты при их поступлении.
Вот пример кода, который загружает несколько URL-адресов:
import multiprocessing, re, subprocess, sys
CMD_LIST = [
["wget", "-qO-", "http://ipecho.net/plain"],
["curl", '-s', "http://www.networksecuritytoolkit.org/nst/cgi-bin/ip.cgi"],
["curl", '-s', "v4.ident.me"],
["curl", '-s', "ipv4.icanhazip.com"],
["curl", '-s', "ipv4.ipogre.com"],
]
ip_pat = re.compile('[0-9.]{7,}')
pool = multiprocessing.Pool(5)
for output in pool.imap_unordered(subprocess.check_output, CMD_LIST):
print 'output:',output
m = ip_pat.search(output)
if m:
print 'GOT IP:', m.group(0)
pool.terminate()
sys.exit(0)
print 'no IP found'