Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 可以并行运行以下web查询吗?_Python_Multithreading_Parallel Processing_Modbus_Modbus Tk - Fatal编程技术网

Python 可以并行运行以下web查询吗?

Python 可以并行运行以下web查询吗?,python,multithreading,parallel-processing,modbus,modbus-tk,Python,Multithreading,Parallel Processing,Modbus,Modbus Tk,我正在使用Python来轮询nPLC。每次投票大约需要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 使

我正在使用Python来轮询
n
PLC。每次投票大约需要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
使用。它允许您启动一个进程池,将作业发送到该池,并在它们进入时接收结果

下面是下载一组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'

我不知道modbus_tk,但你能用它吗?为每个要轮询的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

多道处理在这里也会起作用,尽管这对于这个问题来说太过分了。因为这是一个I/O操作,所以它是线程的理想候选者。GIL(全局解释器锁)不会让你慢下来,线程比进程轻。

为什么不使用线程?在nix系统上,进程是便宜的,所以不会有太多的开销。如果OP恰好使用windows,那么开销将远远高于线程…@wallacer:好的观点。对于OP关于多个I/O绑定作业的问题,线程的开销确实会更低,尤其是在Windows上。我建议使用
多处理
,因为它更容易编程。
本身就让很多事情变得容易得多<代码>线程化级别太低。一般来说,每个ip地址生成一个线程是个坏主意。首先,特别是对于32位进程,您很容易耗尽所有这些线程的资源,其次,拥有数千个线程将导致糟糕的性能。但由于我怀疑任何临时用户都会有数千个PLC,所以在这种情况下没关系。@Voo是的,如果您的用例涉及到数千个PLC,那么您可能希望每个轮询线程批处理多个IP。不过,我想,正如你所说的,这不是OP的用例,所以我提出了一个简单的解决方案,应该给他提高性能,他希望能找到任何一个答案,你应该考虑接受一个……Walac,我会的,我已经尝试了你提供的代码,虽然只有4个活跃IP,我有,我在秒表上得到了相同的速度(大约13秒)。我想回来回答是什么解决了我的问题。这是令人惊讶的。。。是的,如果不能解决您的问题,请不要接受;)你有没有试过在里面放一些简单的计时代码和打印?即使只是在每个线程的run方法的末尾打印一次,也可以让您看到它们是否在某个地方遇到瓶颈并互相等待——这可以解释时间大致相同的原因。