【问题标题】:How to call mutiple function at the same time without waiting for function completed如何在不等待函数完成的情况下同时调用多个函数
【发布时间】:2021-08-01 21:11:11
【问题描述】:

我想编写一个代码来同时 ping 多个 IP。函数如下:

import multiprocessing
import subprocess

IPs = {"google": "8.8.8.8",
       "google2":"8.8.4.4",
       "cloudflare": "1.1.1.1",
        "cloudflare2":"1.0.0.1"
       } # not fixed length, different number of IPs each time

def pinghost(name, host):
    print(f"start ping {name} - {host}")
    cmd = ["ping", host]
    ping_reply = subprocess.check_output(cmd)
    print(ping_reply)
    print(f"end ping {name} - {host}")

def main(IPs):
    p = multiprocessing.Pool()
    for i in IPs:
        print(i, IPs[i])
        p.apply_async(func=pinghost(i, IPs[i]))
    p.close()
    p.join()

main(IPs)

虽然我使用了apply_async,但看起来它仍在等待这些IP一一ping通。

google 8.8.8.8
start ping google - 8.8.8.8
b'\r\nPinging 8.8.8.8 with 32 bytes of data:\r\nReply from 8.8.8.8: bytes=32 time=12ms TTL=116\r\nReply from 8.8.8.8: bytes=32 time=12ms TTL=116\r\nReply from 8.8.8.8: bytes=32 time=13ms TTL=116\r\nReply from 8.8.8.8: bytes=32 time=23ms TTL=116\r\n\r\nPing statistics for 8.8.8.8:\r\n    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\nApproximate round trip times in milli-seconds:\r\n    Minimum = 12ms, Maximum = 23ms, Average = 15ms\r\n'
end ping google - 8.8.8.8
google2 8.8.4.4
start ping google2 - 8.8.4.4
b'\r\nPinging 8.8.4.4 with 32 bytes of data:\r\nReply from 8.8.4.4: bytes=32 time=13ms TTL=116\r\nReply from 8.8.4.4: bytes=32 time=10ms TTL=116\r\nReply from 8.8.4.4: bytes=32 time=14ms TTL=116\r\nReply from 8.8.4.4: bytes=32 time=9ms TTL=116\r\n\r\nPing statistics for 8.8.4.4:\r\n    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\nApproximate round trip times in milli-seconds:\r\n    Minimum = 9ms, Maximum = 14ms, Average = 11ms\r\n'
end ping google2 - 8.8.4.4
cloudflare 1.1.1.1
start ping cloudflare - 1.1.1.1
b'\r\nPinging 1.1.1.1 with 32 bytes of data:\r\nReply from 1.1.1.1: bytes=32 time=8ms TTL=58\r\nReply from 1.1.1.1: bytes=32 time=5ms TTL=58\r\nReply from 1.1.1.1: bytes=32 time=9ms TTL=58\r\nReply from 1.1.1.1: bytes=32 time=14ms TTL=58\r\n\r\nPing statistics for 1.1.1.1:\r\n    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\nApproximate round trip times in milli-seconds:\r\n    Minimum = 5ms, Maximum = 14ms, Average = 9ms\r\n'
end ping cloudflare - 1.1.1.1
cloudflare2 1.0.0.1
start ping cloudflare2 - 1.0.0.1
b'\r\nPinging 1.0.0.1 with 32 bytes of data:\r\nReply from 1.0.0.1: bytes=32 time=13ms TTL=58\r\nReply from 1.0.0.1: bytes=32 time=11ms TTL=58\r\nReply from 1.0.0.1: bytes=32 time=9ms TTL=58\r\nReply from 1.0.0.1: bytes=32 time=12ms TTL=58\r\n\r\nPing statistics for 1.0.0.1:\r\n    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\nApproximate round trip times in milli-seconds:\r\n    Minimum = 9ms, Maximum = 13ms, Average = 11ms\r\n'
end ping cloudflare2 - 1.0.0.1

那么如何同时ping这些IP呢?(同时调用函数,不等待结果)

我也试过aysncio,也是一样,都是一个个ping IP。

async def pinghost(name, host):
    print(f"start ping {name} - {host}")
    cmd = ["ping", host]
    ping_reply = subprocess.check_output(cmd)
    print(ping_reply)
    print(f"end ping {name} - {host}")

async def main(IPs):
    for i in IPs:
        print(i)
        await pinghost(i, IPs[i])

asyncio.run(main(IPs))

【问题讨论】:

  • 您的代码相对简单,所以如果它在新线程有机会初始化和启动之前完成,我不会感到惊讶
  • @AndyKnight,谢谢,看起来像线程工作。

标签: python async-await


【解决方案1】:

你可以试试这个:

import multiprocessing
import subprocess
from multiprocessing import Pool


IPs = {"google": "8.8.8.8",
       "google2":"8.8.4.4",
       "cloudflare": "1.1.1.1",
        "cloudflare2":"1.0.0.1"
       } # not fixed length, different number of IPs each time

def pinghost(host):
    print(f"start ping {host}")
    cmd = ["ping", host]
    ping_reply = subprocess.check_output(cmd)
    print(ping_reply)
    print(f"end ping {host}")

def main(IPs):
    
    with Pool(5) as p:
        p.map(pinghost, list(IPs.values()))
    


main(IPs)

【讨论】:

    【解决方案2】:

    按照 Andy 的建议,使用线程工作。

    def pinghost(name, host):
        print(f"start ping {name} - {host}")
        cmd = ["ping", host]
        ping_reply = subprocess.check_output(cmd)
        print(ping_reply)
        print(f"end ping {name} - {host}")
    
    def main(IPs):
        threads = list()
        for i in IPs:
            x = threading.Thread(target=pinghost, args=(i, IPs[i]))
            threads.append(x)
            x.start()
    
    

    我发现这里很棘手,一开始我在使用

            x = threading.Thread(target=pinghost(i, IPs[i]))
    

    它不起作用,必须使用

            x = threading.Thread(target=pinghost, args=(i, IPs[i]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多