<p>这听起来很适合使用<a href="https://docs.python.org/3/library/concurrent.futures.html" rel="nofollow">^{<cd1>}</a>一种提交和控制多个作业的方式。在这里,您有许多助手线程来完成调用子进程的后腿工作,还有一个主线程来收集结果并决定如何处理它们。例如:</p>
<pre><code>from concurrent.futures import ThreadPoolExecutor, as_completed
from time import sleep
from random import random
job_count = 10
def is_even(x):
return x % 2 == 0
def do_something(i):
"All odd jobs complete before even jobs"
if not is_even(i):
return i
sleep(0.1 + random())
return i
with ThreadPoolExecutor(max_workers=job_count) as executor:
successful_result = None
futures = [executor.submit(do_something, i) for i in range(job_count)]
for future in as_completed(futures):
result = future.result()
if is_even(result):
successful_result = result
break
print("the first successful result was:", successful_result)
</code></pre>
<p>适用于您的问题:</p>
<pre><code>def getIP(self, commandline):
getter_process = subprocess.Popen(commandline, stdout=subprocess.PIPE)
myip = getter_process.communicate()[0].decode(encoding="ascii", errors="ignore").replace("\n","")
return myip if isIP(myIP) else None
def askIP(self,ind):
"""
Start subprocesses asking for external IP in separate threads
"""
print("askIP start")
#list of commandlines that are supposed to return IP as a result
IPgettingMethods = [
["dig", "+short", "myip.opendns.com", "@resolver1.opendns.com"],
["dig", "+short", "myip.opendns.com", "@resolver1.opendns.com"],
# and other command line commands I may want in separate threads
]
def get_ip_controller():
with ThreadPoolExecutor(len(IPgettingMethods)) as executor:
futures = [executor.submit(self.getIP, i) for i in IPgettingMethods]
for future in as_completed(futures):
ip = future.result()
if ip:
GLib.idle_add(self.setIndicatingMenus, ip, self.hIndicator)
break
Thread(target=get_ip_controller).start()
</code></pre>