• python的多线程使用


    1、多线程的使用方式

    1.1 方式1 :直接使用

    # -*- coding:utf-8 -*-
    # 线程使用的方式一
    import threading
    import time
    
    
    # 需要多线程运行的函数
    def fun(args):
        print("我是线程%s" % args)
        time.sleep(2)
        print("线程%s运行结束" % args)
    
    # 创建线程
    t1 = threading.Thread(target=fun, args=(1,))
    t2 = threading.Thread(target=fun, args=(2,))
    start_time = time.time()
    t1.start()
    t2.start()
    end_time = time.time()
    print("两个线程一共的运行时间为:", end_time-start_time)
    print("主线程结束")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    执行结果:

    运行结果:
    我是线程1
    我是线程2
    两个线程一共的运行时间为: 0.0010077953338623047
    主线程结束
    
    线程1运行结束
    线程2运行结束
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.2 方式2:继承类调用

    # 继承式调用
    import threading
    import time
    
    
    class MyThreading(threading.Thread):
        def __init__(self, name):
            super(MyThreading, self).__init__()
            self.name = name
    
        # 线程要运行的代码
        def run(self):
            print("我是线程%s" % self.name)
            time.sleep(2)
            print("线程%s运行结束" % self.name)
    
    
    t1 = MyThreading(1)
    t2 = MyThreading(2)
    start_time = time.time()
    t1.start()
    t2.start()
    end_time = time.time()
    print("两个线程一共的运行时间为:", end_time-start_time)
    print("主线程结束")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    执行结果:

    运行结果:
    我是线程1
    我是线程2
    两个线程一共的运行时间为: 0.0010724067687988281
    主线程结束
    线程2运行结束
    线程1运行结束
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、守护线程与join方法

    • 当开启子线程的守护线程,若主线程结束,则子线程立马全部结束;若不开启守护线程,主线程结束后,子线程会继续执行直到自行结束。
    • 在Python多线程中,join方法的作用是线程同步,即主程序将一直等待子程序全部运行完成才结束。

    2.1 默认情况

    Python多线程默认情况是没有设置守护线程(即设置线程setDaemon(False)),主线程执行完自己的任务后,就退出了,此时子线程会继续执行自己的任务,直到子线程任务结束。以上两个例子都是。

    2.2 守护线程

    ​ 开启线程的setDaemon(True)),设置子线程为守护线程,实现主程序结束,子程序立马全部结束功能

    # 守护线程
    import threading
    import time
    
    
    class MyThreading(threading.Thread):
        def __init__(self, name):
            super(MyThreading, self).__init__()
            self.name = name
    
        # 线程要运行的代码
        def run(self):
            print("我是线程%s" % self.name)
            time.sleep(2)
            print("线程%s运行结束" % self.name)
    
    
    t1 = MyThreading(1)
    t2 = MyThreading(2)
    start_time = time.time()
    t1.setDaemon(True)
    t1.start()
    t2.setDaemon(True)
    t2.start()
    end_time = time.time()
    print("两个线程一共的运行时间为:", end_time-start_time)
    print("主线程结束")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    **注意:**如果要设置为守护线程,一定要在开启线程之前(start()),将该线程设置为守护线程。

    **结论:**主线程结束后,无论子线程1,2是否运行完成,都结束线程,不再继续向下运行。

    2.3 join方式

    当不开启守护进程时,主程序将一直等待子程序全部运行完成才结束。

    # join:线程同步
    import threading
    import time
    
    
    class MyThreading(threading.Thread):
        def __init__(self, name):
            super(MyThreading, self).__init__()
            self.name = name
    
        # 线程要运行的代码
        def run(self):
            print("我是线程%s" % self.name)
            time.sleep(3)
            print("线程%s运行结束" % self.name)
    
    
    threading_list = []
    start_time = time.time()
    for x in range(50):
        t = MyThreading(x)
        t.start()
        threading_list.append(t)
    
    for x in threading_list:
        x.join()    # 为线程开启同步
    
    end_time = time.time()
    print("50个线程一共的运行时间为:", end_time-start_time)
    print("主线程结束")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    **结论:**主线程等待50个子线程全部执行完成才结束。

    3、线程池

    ​ Python3中官方才正式提供线程池,而且线程不是开的越多越好,开的多了可能会导致系统的性能更低。

    import time
    from concurrent.futures import ThreadPoolExecutor  # 并行期货,线程池执行者
    """
    pool = ThreadPoolExecutor(100)
    pool.submit(函数名,参数1,参数2,参数...)
    """
    
    
    def task(video_url, num):
        print("开始执行任务", video_url, num)     # 开始执行任务 www.xxxx-299.com 3
        time.sleep(1)
    
    
    # 创建线程池,最多维护10个线程
    threadpool = ThreadPoolExecutor(10)
    # 生成300网址,并放入列表
    url_list = ["www.xxxx-{}.com".format(i) for i in range(300)]
    for url in url_list:
        """
        在线程池中提交一个任务,线程池如果有空闲线程,则分配一个线程去执行,执行完毕后在将线程交还给线程池,
        如果没有空闲线程,则等待。注意在等待时,与主线程无关,主线程依然在继续执行。
        """
        threadpool.submit(task, url, 3)
    
    print("等待线程池中的任务执行完毕中······")
    threadpool.shutdown(True)   # 等待线程池中的任务执行完毕后,在继续执行
    print("END")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    参考文章

  • 相关阅读:
    C++将派生类赋值给基类
    微信小程序 | 基于云数据库的许愿墙
    Python os模块:整理文件和目录最最最常用的模块
    UE里的Sync Groups
    【2022】58同城前端笔试
    【电子学会】2023年03月图形化四级 -- 求和
    xxl-job源码解读:路由策略ExecutorRoute
    SAP 采购订单免费标识自动勾选的判断依据
    VR机器人教你如何正确打乒乓球
    如何最简单的在conda环境中使用pip
  • 原文地址:https://blog.csdn.net/Kevin_Xie86/article/details/126468979