python线程的实现方式

参考文章

python线程池 ThreadPoolExecutor 的用法及实战

创建 threading.Thread

threading.Thread 构造方法:

threading.Thread(group=None, target=None, name=None,args=(), kwargs=None, *, daemon=None
  1. group:应为None,预留给将来扩展ThreadGroup时使用类实现。
  2. target:要调用的函数
  3. name:线程名,默认是Thread-1,Thread-2… Thread-N
  4. args:函数的可变参数
  5. kwargs:函数的关键词参数
  6. daemon:是否是守护进程,True 是,False 不是
import random
import threading
import time


def doing(person, task):
    thread_name = threading.current_thread().name
    print("threadName=%s : %s start %s " % (thread_name, person, task))
    time.sleep(random.randrange(start=1, stop=5))
    print("threadName=%s : %s end %s " % (thread_name, person, task))


def test1():
    for i in range(0, 3):
        my_thread = threading.Thread(target=doing, args=("%d 号工人" % i, "%d 号任务" % i))
        my_thread.start()


if __name__ == "__main__":
    test1()

运行结果:

threadName=Thread-1 : 0 号工人 start 0 号任务 
threadName=Thread-2 : 1 号工人 start 1 号任务 
threadName=Thread-3 : 2 号工人 start 2 号任务 
threadName=Thread-2 : 1 号工人 end 1 号任务 
threadName=Thread-1 : 0 号工人 end 0 号任务 
threadName=Thread-3 : 2 号工人 end 2 号任务 

继承 threading.Thread

import random
import threading
import time

class DoingThread(threading.Thread):
    def __init__(self, person, task):
        super(DoingThread, self).__init__()
        self.person = person
        self.task = task

    def run(self):
        thread_name = threading.current_thread().name
        print("threadName=%s : %s start %s " % (thread_name, self.person, self.task))
        time.sleep(random.randrange(start=1, stop=5))
        print("threadName=%s : %s end %s " % (thread_name, self.person, self.task))


def test2():
    for i in range(0, 3):
        my_thread = DoingThread("%d 号工人" % i, "%d 号任务" % i)
        my_thread.start()


if __name__ == "__main__":
    test2()

运行结果:

threadName=Thread-1 : 0 号工人 start 0 号任务 
threadName=Thread-2 : 1 号工人 start 1 号任务 
threadName=Thread-3 : 2 号工人 start 2 号任务 
threadName=Thread-2 : 1 号工人 end 1 号任务 
threadName=Thread-3 : 2 号工人 end 2 号任务 
threadName=Thread-1 : 0 号工人 end 0 号任务 

线程池 concurrent.futures

从Python3.2开始,标准库为我们提供了 concurrent.futures 模块,它提供了 ThreadPoolExecutor (线程池)

相比 threading 等模块,该模块通过 submit 返回的是一个 future 对象,它是一个未来可期的对象,通过它可以获取某线程执行的状态和返回值

import random
import time
import threading
from concurrent.futures import ThreadPoolExecutor


def doing(person, task):
    thread_name = threading.current_thread().name
    print("threadName=%s : %s start %s " % (thread_name, person, task))
    time.sleep(random.randrange(start=1, stop=5))
    print("threadName=%s : %s end %s " % (thread_name, person, task))
    return thread_name


def test3():
    # 创建一个最大容纳数量为2的线程池
    with ThreadPoolExecutor(max_workers=3) as executor:
        items = []
        for i in range(0, 3):
            item = executor.submit(doing, "%d 号工人" % i, "%d 号任务" % i)
            items.append(item)

        results = []
        for item in items:
            results.append(item.result())

        print(results)


if __name__ == "__main__":
    test3()

运行结果:

threadName=ThreadPoolExecutor-0_0 : 0 号工人 start 0 号任务 
threadName=ThreadPoolExecutor-0_1 : 1 号工人 start 1 号任务 
threadName=ThreadPoolExecutor-0_2 : 2 号工人 start 2 号任务 
threadName=ThreadPoolExecutor-0_0 : 0 号工人 end 0 号任务 
threadName=ThreadPoolExecutor-0_2 : 2 号工人 end 2 号任务 
threadName=ThreadPoolExecutor-0_1 : 1 号工人 end 1 号任务 
['ThreadPoolExecutor-0_0', 'ThreadPoolExecutor-0_1', 'ThreadPoolExecutor-0_2']

future.result(timeout=None) : 获取线程的运行结果,如果没有执行完成,则一直等待(或等待timeout),直到有结果。

所有上面的结果顺序和执行顺序一样,即使ThreadPoolExecutor-0_2 比 ThreadPoolExecutor-0_1 更早的结束。

as_completed

谁执行的快就获取谁的结果。当线程池中有子线程中的执行结束,马上返回该线程,用 result() 获取返回结果,不要像上面一样按执行顺序获取结果、

def test3():
    # 创建一个最大容纳数量为2的线程池
    with ThreadPoolExecutor(max_workers=3) as executor:
        items = []
        for i in range(0, 3):
            item = executor.submit(doing, "%d 号工人" % i, "%d 号任务" % i)
            items.append(item)

        results = []
        # for item in items:
        for item in as_completed(items):
            results.append(item.result())

        print(results)

运行结果:

threadName=ThreadPoolExecutor-0_0 : 0 号工人 start 0 号任务 
threadName=ThreadPoolExecutor-0_1 : 1 号工人 start 1 号任务 
threadName=ThreadPoolExecutor-0_2 : 2 号工人 start 2 号任务 
threadName=ThreadPoolExecutor-0_1 : 1 号工人 end 1 号任务 
threadName=ThreadPoolExecutor-0_0 : 0 号工人 end 0 号任务 
threadName=ThreadPoolExecutor-0_2 : 2 号工人 end 2 号任务 
['ThreadPoolExecutor-0_1', 'ThreadPoolExecutor-0_0', 'ThreadPoolExecutor-0_2']

猜你喜欢

转载自blog.csdn.net/fangye1/article/details/112248260
今日推荐