Python如何获取多线程返回结果

  

获取多线程返回结果是使用Python多线程编程的重要部分。下面我们将分为以下几个步骤来详细讲解如何获取多线程返回结果。

1.导入必要的库

首先,建议导入必要的库: threading和Queue。

import threading
from queue import Queue

2.创建线程类

在创建线程的时候,我们可以通过Thread类继承并重写run()方法的方式来实现。注意在run()方法中计算完成后需要将结果存入队列。

class MyThread(threading.Thread):
    def __init__(self, name, args, queue):
        threading.Thread.__init__(self)
        self.name = name
        self.args = args
        self.queue = queue

    def run(self):
        print("线程 %s 开始" % self.name)
        # 假设这里是计算过程
        res = self.args * 2
        self.queue.put(res)
        print("线程 %s 结束" % self.name)

3.创建线程并启动

在创建线程时,需指定线程名、参数和结果队列。

threads = []
results = Queue()

for i in range(5):
    t = MyThread("Thread %s" % i, i, results)
    threads.append(t)
    t.start()

由于涉及到多线程,那么就需要等待所有线程都执行完成后,才能对所有结果进行处理。我们可以使用join()方法等待所有线程结束。

for t in threads:
    t.join()

4.处理结果

由于结果队列中的内容可能较多,我们可以使用队列的get方法,轮询每个线程的结果,并将其存储到一个列表中,最终得到所有的结果。

output = []
while not results.empty():
    output.append(results.get())

5.完整代码实例

import threading
from queue import Queue

class MyThread(threading.Thread):
    def __init__(self, name, args, queue):
        threading.Thread.__init__(self)
        self.name = name
        self.args = args
        self.queue = queue

    def run(self):
        print("线程 %s 开始" % self.name)
        # 假设这里是计算过程
        res = self.args * 2
        self.queue.put(res)
        print("线程 %s 结束" % self.name)

threads = []
results = Queue()

for i in range(5):
    t = MyThread("Thread %s" % i, i, results)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

output = []
while not results.empty():
    output.append(results.get())

print(output)

6.示例说明

为了更加理解上述代码,我们以下面的两个具体示例进行说明:

(1)获取多个URL的web内容示例:

在执行多线程之前,我们需要创建get_content()函数,用于获取每个URL的web内容。

import urllib.request

def get_content(url):
    res = urllib.request.urlopen(url)
    content = res.read()
    return content.decode('utf-8')

接下来,我们创建一个线程类,并在其中调用get_content()函数。

class ContentGetter(threading.Thread):
    def __init__(self, url, queue):
        threading.Thread.__init__(self)
        self.url = url
        self.queue = queue

    def run(self):
        content = get_content(self.url)
        self.queue.put(content)

最后,我们可以创建多个线程用来获取多个URL的web内容:

thread_pool = []
result_queue = Queue()

urls = ["http://www.python.org", "http://www.baidu.com", "http://www.google.com", "http://www.qq.com"]

for url in urls:
    t = ContentGetter(url, result_queue)
    thread_pool.append(t)
    t.start()

for t in thread_pool:
    t.join()

while not result_queue.empty():
    result = result_queue.get()
    print("Content of url is %s" % result)

(2)获取多个IP的ping值示例:

在执行多线程之前,我们需要创建ping()函数,用于获取每个IP的ping值。

import subprocess

def ping(ip):
    p = subprocess.Popen(["ping.exe",ip], stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
    p.wait()
    result = p.stdout.readlines()
    return result

接下来,我们创建一个线程类,并在其中调用ping()函数。

class Pinger(threading.Thread):
    def __init__(self, ip, queue):
        threading.Thread.__init__(self)
        self.ip = ip
        self.queue = queue

    def run(self):
        result = ping(self.ip)
        self.queue.put(result)

最后,我们可以创建多个线程用来获取多个IP的ping值:

thread_pool = []
result_queue = Queue()

ips = ["127.0.0.1", "192.168.1.1", "10.0.0.1"]

for ip in ips:
    t = Pinger(ip, result_queue)
    thread_pool.append(t)
    t.start()

for t in thread_pool:
    t.join()

while not result_queue.empty():
    result = result_queue.get()
    print("Ping result of ip is %s" % result)
相关文章