【问题标题】:multithreading dilemma多线程困境
【发布时间】:2017-12-25 03:55:14
【问题描述】:

这里是代码。 计划是 ping 范围内的所有主机并恢复 fqdn...这是有效的,但需要很长时间...所以考虑多处理...但无法使其正常工作。代码只是挂在 p.map(...) 并没有超出。 有人可以帮忙吗?......希望代码是可读的..

import subprocess
import os
import socket
import multiprocessing
from multiprocessing.dummy import Pool as ThreadPool 
from datetime import datetime



range_85 = "10.85.40"
range_87 = "10.87.40"

print ("starting")

replyfile = open("pingdns_replies.txt", "a")
#replyfile.write("START %s \n" % datetime.now())

print("file opened")


def ping(host):
        print ("entered function")
        #for ip in range (50,250):
                #host = range_85 +"."+ str(ip)
        print (host)
        rep = subprocess.call("ping %s" % host, shell=False)
        if rep == 0:   
                try:
                        dns = socket.getfqdn(host)
                except:
                        dns = " "
                        print ("%s at %s is up" % (dns, host))
                        replyfile.write(" %s at %s is up \n" % (dns, host))
        else:
                try:
                        dns = socket.getfqdn(host)
                        print("%s at %s is down ?" % (dns, host))
                        replyfile.write(" %s at %s is down ? \n" % (dns,host))
                except:
                        dns = " "
                        print ("%s received no reply" % host)
                        replyfile.write(" %s received no reply \n" % (dns, host))

#ips = (range_85 + "." + str(i) for i in range(0,255))

ips = []
for i in range(1,255):
        ips.append(range_85+'.'+str(i))


print ("ips created")
print (ips)


with multiprocessing.Pool(2) as p:        
        p.map(ping, ips)

replyfile.write("END %s \n" % datetime.now())
replyfile.close()

【问题讨论】:

  • 请编辑您的代码以使其可读。
  • 如果您将ping 作为子进程调用,则不需要多处理;您已经在使用多个进程。
  • @Daniel....ping 整个范围需要一个小时....有没有办法通过产生多个进程来处理它来使其更快?...只是引入多处理在那一点上挂起,甚至没有到达 def ping(host)

标签: python multithreading


【解决方案1】:

此代码不完整,因此很难确定, 但您似乎正在尝试在此行中创建要扫描的 ips 列表:

ips = range_85 +"."+ str('%d' % i for i in range(1,254))

问题在于 str() 转换,您将生成器对象转换为字符串,而不是实际从生成器的每个元素生成字符串

要为您的 ip 范围创建生成器,您可以将该行替换为以下内容:

ips = ( range_85 + "." + str(i) for i in range(1,254))

我应该注意,您将 0 和 254 从您的 ip 范围中排除在您的 ip 范围内仍然有效(即使您不想 ping 10.85.40.255) range(0,255) 会给您整个 ip 范围(不包括第255章)

编辑

鉴于问题已完全改变,以下是新问题的答案:

您对 ping 的调用永远不会返回,至少在 linux 上“ping xx.xx.xx.xx”将无限期发送 icmp 数据包,直到它被 SIGINT 停止

你可以参考这里的ping文档:https://linux.die.net/man/8/ping

尝试换行

rep = subprocess.call("ping 1 %s" % host, shell=False)

rep = subprocess.call("ping -c 1 %s" % host, shell=False)

请注意,如果您想确保随机丢包不会影响结果,您可以而且应该发送多个数据包。

您似乎只使用了一个由 2 个线程组成的线程池,除非您难以置信地缺乏资源,否则您可以使用更多的资源(如果您使用的是普通 PC,可能会使用数百个),因为 ping命令不需要很多 cpu 电源,它只是挂起等待答案。

最后一点:您正在从多个位置写入同一个文件,我建议您不要这样做,而是在文件调用周围使用互斥锁或使用多处理线程安全容器来保存结果,然后从一切完成后,文件的主线程

【讨论】:

  • )) #ips = (range_85 + "." + str(i) for i in range(0,255)) ips = [] for i in range(1,255): ips.append(range_85+' .'+str(i)) 现在生成这样的范围,它转到这个多代码,但调用一个函数不起作用,multiprocessing.Pool(2) as p: p.map(ping, ips)
  • @ramzal 请学习格式化,否则无法理解您要问的内容。
  • 这就是我想要弄清楚的......遗憾的是还没有运气。
  • @Chris...重新发布了问题,这次格式化了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2014-06-12
  • 1970-01-01
相关资源
最近更新 更多