线程和解释器关闭

2024-09-29 19:23:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一段python代码:

def __init__(self):
  self.ip_list=[]
  self.queue=Queue()

  for i in range(5):
    worker=threading.Thread(target=self.__executeCmd, name="executeCmd("+str(i)+")")
    worker.setDaemon(True)
    worker.start()
  self.queue.put(["wget", "-qO-", "http://ipecho.net/plain"])
  self.queue.put(["curl", "http://www.networksecuritytoolkit.org/nst/cgi-bin/ip.cgi"])
  self.queue.put(["curl", "v4.ident.me"])
  self.queue.put(["curl", "ipv4.icanhazip.com"])
  self.queue.put(["curl", "ipv4.ipogre.com"])

def __executeCmd(self):
  cmd=self.queue.get()
  try:
    rc=subprocess.check_output(cmd, stderr=open(os.devnull, 'w')).strip()
  except:
    self.queue.task_done()
    return
  if self.is_valid_ip(rc)==True:
    self.ip_list.append(rc)
  self.queue.task_done()

def waitForIP(self, wait_in_sec):
  cnt=wait_in_sec*10
  while self.ip_list==[]:
    time.sleep(0.1)
    cnt-=1
    if cnt<=0:
      return("")
  return(self.ip_list[0])

它用于从五个url中查询外部IP地址,并从最先传递的那个url获得响应。在

但有时我会收到(我通过电子邮件收到,因为工作是通过crontab启动的):

^{pr2}$

我想这是因为脚本已经结束,但是一个线程仍然在运行,然后就出来了subprocess.check_输出(). 在

有没有一种方法可以避免这种情况(不用等待所有五个url都发送了它们的数据)?在


Tags: inselfiptrueurlreturnqueueput
1条回答
网友
1楼 · 发布于 2024-09-29 19:23:45

这个项目比看上去简单得多。下面是一个使用multiprocessing模块的实现。在

函数imap_unordered并行运行这些作业,并首先返回第一个完成的作业。外部级别功能检查结果。如果结果正常,则打印它,然后终止池并退出整个程序。它不会等待其他工作完成。在

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'

相关问题 更多 >

    热门问题