线程和多任务

多任务

多任务介绍

  • 同时做多件事就是多任务,重点就是同时进行。

多任务理解

  • 这里提出两个概念,并发和并行。
    • 并发:CPU数量小于当前执行的多任务,假的多任务,并不是同一时刻才运行所有任务,而是通过时间片轮转的方式,高速的切换运行的任务达到短时间内运行多个任务的结果。
    • 并行:CPU数量大于当前执行的多任务,真的多任务,因为CPU数量足够,所以每个任务由不同的CPU执行,实现了同时进行。在这里插入图片描述

实现多任务方式

  • 实现多任务有三种方式:
    • 线程
    • 进程
    • 协程

线程

线程介绍

  • 线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

使用线程完成多任务

import threading    # 内置模块
import time


def demo():
    for i in range(3):
        print("hello world")
        time.sleep(1)


if __name__ == '__main__':
    t = threading.Thread(target=demo)
    t.start()
    print("1")
  • 主线程会等到子线程结束之后才会结束在这里插入图片描述
  • 从这个运行结果中也可以看出上面的结论,在第一次循环的时候,print语句已经执行,表示主线程已经执行完毕,但程序并没有结束,而是等到子线程的5次循环全部完成之后,才结束。
  • 如果不想等待子线程结束后才结束,可以加入守护线程,如下:
import threading
import time

def main():
    for i in range(5):
        print('helloworld')
        time.sleep(1)

if __name__ == '__main__':

        t = threading.Thread(target=main,daemon=True)

        t.start()
        print('1')
  • 加入守护线程即选择Thread的参数daemon为True,也可以写t.daemon(True)。daemon译为守护线程,加入了守护线程后,运行的结果为:在这里插入图片描述
  • 可以看出主线程并没有等待子线程的循环结束,再运行了print语句之后直接结束,子线程后面的循环也就看不到了。
  • 除了守护线程之外,还有一个join方法,可以让主线程等待子线程执行完毕之后再执行,代码如下:
import threading
import time

def main():
    for i in range(5):
        print('helloworld')
        time.sleep(1)

if __name__ == '__main__':

        t = threading.Thread(target=main)

        t.start()

        t.join()

        print('1')

  • 运行结果如下:在这里插入图片描述
  • 不同于前两次的运行结果,加入了join之后,主线程会等待子线程运行结束,也就是子线程的循环完全结束,才会继续往下执行,而不是像第一个例子那样,先执行完主线程但不结束等待子线程运行完成,这里的顺序有一些不同。

查看线程数量

  • 可以通过threading模块里面的enumerate来查看线程的数量
import threading
import time


def demo1():
    for i in range(3):
        print(f"--demo1--{i}")
        time.sleep(1)


def demo2():
    for i in range(3):
        print(f"--demo2--{i}")
        time.sleep(1)


def main():
    t1 = threading.Thread(target=demo1)
    t2 = threading.Thread(target=demo2)

    t1.start()
    t2.start()
    
    print(threading.enumerate())
    
    
if __name__ == '__main__':
    main()

验证子线程的执行和创建

  • 当调用Thread的时候,不会创建线程。
  • 当调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及开始运行这个线程。
  • 这里通过上面的查看线程数量的代码来查看子线程创建的过程
import threading
import time


def demo1():
    for i in range(3):
        print(f"--demo1--{i}")
        time.sleep(1)


def demo2():
    for i in range(3):
        print(f"--demo2--{i}")
        time.sleep(1)


def main():
    print('创建前:',threading.enumerate())
    t1 = threading.Thread(target=demo1)
    t2 = threading.Thread(target=demo2)
    print('创建后:',threading.enumerate())
    t1.start()
    t2.start()

    print('运行后:',threading.enumerate())


if __name__ == '__main__':
    main()
  • 代码的执行结果如下:在这里插入图片描述
  • 通过结果我们也可以印证上面的结论,即子线程是在运行之后才创建出来的。

继承Thread类创建线程

import threading
import time

class A(threading.Thread):
    
    def __init__(self,name):
        super().__init__(name=name)
    
    def run(self):
        for i in range(5):
            print(i)

if __name__ == "__main__":
    t = A('test_name')    
    t.start()       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值