zoukankan      html  css  js  c++  java
  • Python-Thread(通俗易懂)

        此类表示在单独的控制线程中运行的活动,有两种方法可以指定该活动,一是将可调用对象传递给构造函数,二是通过覆盖子类中的run()方法。

      如果你对线程不太理解,我们可以打个比方,把线程数看作车辆数,我们来完成一个简单的客运运输工作(以下为了方便理解,也加入相应注释)。

      更多threading模块函数和对象说明,可参考:https://www.cnblogs.com/leozhanggg/p/10317494.html

    一、无线程:
    示例:
    import time
    start = time.time()
    people = 500      # 假设有500个人
    def action(num):
        global people
        while people>0:
            people -= 50     # 每次运输50人
            print("车辆编号:%d, 当前车站人数:%d" %(num, people))
            time.sleep(1)
            
    num = 1     # 车辆编号
    action(num)
    end = time.time()
    print("Duration time: %0.3f" %(end-start))
    运行结果:
    C:Python37python.exe Y:/Project-python/threading/test.py
    车辆编号:1, 当前车站人数:450
    车辆编号:1, 当前车站人数:400
    车辆编号:1, 当前车站人数:350
    车辆编号:1, 当前车站人数:300
    车辆编号:1, 当前车站人数:250
    车辆编号:1, 当前车站人数:200
    车辆编号:1, 当前车站人数:150
    车辆编号:1, 当前车站人数:100
    车辆编号:1, 当前车站人数:50
    车辆编号:1, 当前车站人数:0
    Duration time: 10.001
    
    Process finished with exit code 0


    二、单线程:
    编码示例:
    import threading
    import time
    start = time.time()
    people = 500      # 假设有500个人
    def action(num):
        global people
        while people>0:
            people -= 50     # 每次运输50人
            print("车辆编号:%d, 当前车站人数:%d" %(num, people))
            time.sleep(1)
    
    num = 1     # 车辆编号
    vehicle = threading.Thread(target=action, args=(num,))  # 新建车辆
    vehicle.start()     # 启动车辆
    vehicle.join()      # 检查到站车辆
    
    end = time.time()
    print("Duration time: %0.3f" %(end-start))
    运行结果:
    C:Python37python.exe Y:/Project-python/threading/test.py
    车辆编号:1, 当前车站人数:450
    车辆编号:1, 当前车站人数:400
    车辆编号:1, 当前车站人数:350
    车辆编号:1, 当前车站人数:300
    车辆编号:1, 当前车站人数:250
    车辆编号:1, 当前车站人数:200
    车辆编号:1, 当前车站人数:150
    车辆编号:1, 当前车站人数:100
    车辆编号:1, 当前车站人数:50
    车辆编号:1, 当前车站人数:0
    Duration time: 10.001
    
    Process finished with exit code 0
    三、多线程(传递对象方式):
    编码示例:
    # -*- coding: utf-8 -*
    import threading
    import time
    
    people = 500      # 假设有500个人
    def action(num):
        global people
        while people>0:
            people -= 50     # 每次运输50人
            print("车辆编号:%d, 当前车站人数:%d" %(num, people))
            time.sleep(1)
    
    start = time.time()
    vehicles = []       # 新建车辆组
    for num in range(5):
        vehicle = threading.Thread(target=action, args=(num,)) # 新建车辆
        vehicles.append(vehicle)     # 添加车辆到车辆组中
    
    for vehicle in vehicles:
        vehicle.start()  # 分别启动车辆
    
    for vehicle in vehicles:
        vehicle.join()      # 分别检查到站车辆
    end = time.time()
    print("Duration time: %0.3f" % (end-start))
    运行结果:
    C:Python37python.exe Y:/Project-python/threading/test.py
    车辆编号:0, 当前车站人数:450
    车辆编号:1, 当前车站人数:400
    车辆编号:2, 当前车站人数:350
    车辆编号:3, 当前车站人数:300
    车辆编号:4, 当前车站人数:250
    车辆编号:2, 当前车站人数:200
    车辆编号:1, 当前车站人数:150
    车辆编号:0, 当前车站人数:100
    车辆编号:3, 当前车站人数:50
    车辆编号:4, 当前车站人数:0
    Duration time: 2.001
    
    Process finished with exit code 0

    四、多线程(覆盖子类方式

     编码示例:

    # -*- coding: utf-8 -*
    import threading
    import time
    
    people = 500
    class MyThread(threading.Thread):
        def __init__(self, num):
            super(MyThread, self).__init__()
            self.num = num
    
        def run(self):
            global people
            while people > 0:
                people -= 50
                print("车辆编号:%d, 当前车站人数:%d " % (self.num, people))
                time.sleep(1)
    
    start = time.time()
    vehicles = []       # 新建车辆组
    for num in range(5):        # 设置车辆数
        vehicle = MyThread(num)     # 新建车辆
        vehicles.append(vehicle)     # 添加车辆到车辆组中
        vehicle.start()     #启动车辆
    
    for vehicle in vehicles:
        vehicle.join()      # 分别检查到站车辆
    end = time.time()
    print("Duration time: %0.3f" % (end-start))

    运行结果:

    C:Python37python.exe Y:/Project-python/threading/test.py
    车辆编号:0, 当前车站人数:450
    车辆编号:1, 当前车站人数:400
    车辆编号:2, 当前车站人数:350
    车辆编号:3, 当前车站人数:300
    车辆编号:4, 当前车站人数:250
    车辆编号:0, 当前车站人数:200
    车辆编号:2, 当前车站人数:150 车辆编号:3, 当前车站人数:100车辆编号:1, 当前车站人数:50
    
    
    车辆编号:4, 当前车站人数:0
    Duration time: 2.003
    
    Process finished with exit code 0

    五、结果分析

      

      1. 通过结果不难发现,不使用线程类和使用单线程运行时间是一样的,因为我们正常执行一个脚本,本质上就是单线程。

       2. 创建多线程的两种方法运行时间也是一样的,因为最终都是交给Thread类来处理,自行选择即可。

       3. 多线程运行时间明显比单线程快的多,从理论上来说是和线程数成正比的,但是实际并非是线程越多越好,因为线程越多所消耗的资源也就越多。

    六、有关该类的其他说明:

        a. 创建线程对象后,必须通过调用线程的start()方法启动其活动,这将在单独的控制线程中调用run()方法。

        b. 一旦线程的活动开始,线程就被认为是“活着的”,当run()方法终止时,它会停止活动,或者引发异常。

        c. 线程可以调用is_alive()方法测试是否处于活动状态,其他线程可以调用线程的join()方法,这将阻塞调用线程,直到调用其join()方法的线程终止。

        d. 线程有一个名称,这个名称可以传递给构造函数,并通过name属性读取或更改。

        e. 线程可以标记为“守护程序线程”,这个标志的意义在于,当只剩下守护进程线程时,整个Python程序都会退出,可以通过守护程序属性设置该标志。

    ----- 转载请注明原作,谢谢:https://www.cnblogs.com/leozhanggg/p/10335098.html

  • 相关阅读:
    数据结构(2)-链表
    数据结构(1)-数组
    SpringMVC学习总结(一)--Hello World入门
    基本数据类型对象的包装类
    关于String的相关常见方法
    常见的集合容器应当避免的坑
    再一次生产 CPU 高负载排查实践
    分表后需要注意的二三事
    线程池没你想的那么简单(续)
    线程池没你想的那么简单
  • 原文地址:https://www.cnblogs.com/leozhanggg/p/10335098.html
Copyright © 2011-2022 走看看