1.0 多任务的介绍
同时做多件事(多个任务),就可以说是多任务。
并发:cpu小于当前开启的任务,是假的多任务
并行:cpu大于当前开启的任务,是真的多任务
实现多任务的三种方式:
- 线程
- 进程
- 协程
2.0 线程介绍
线程是操作系统能够进行运算调度的最小单位,它被包含在进程当中,是进程中的实际运算单位。
2.1 使用线程完成多任务
##线程间的执行是没有顺序的,是同时进行,但先后顺序可能会变动。
import threading
import time
def demo():
print("hello word")
time.sleep(1)
if __name__ == '__main__':
for i in range(3):
#1.实例化线程
t = threading.Thread(target=demo)
#2.启动主线程,注意:如果没有t.start,则不会启动target指定的函数
t.start()
**注意:
• 主线程会等到子线程执行结束之后主线程,才会结束**
3.0 防护线程
守护线程,也就是说不会等子线程结束
使用方法: t.setDaemon(True)
那是否可以实现子线程结束完毕,主线程才继续执行呢?
使用方法:t.join()
import threading
import time
def ls1():
for i in range(3):
print("正在唱歌")
time.sleep(1)
def ls2():
for i in range(3):
print("正在跳舞")
time.sleep(1)
if __name__ == '__main__':
t1 = threading.Thread(target=ls1)
t2 = threading.Thread(target=ls2)
#使用setDaemon来保护主线程
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()
print("--1--")
输出结果为:
正在唱歌
正在跳舞
--1--
**守护子线程实例:**
import threading
import time
def ls1():
for i in range(3):
print("正在唱歌")
time.sleep(1)
def ls2():
for i in range(3):
print("正在跳舞")
time.sleep(1)
if __name__ == '__main__':
t1 = threading.Thread(target=ls1)
t2 = threading.Thread(target=ls2)
# t1.setDaemon(True)
# t2.setDaemon(True)
t1.start()
t2.start()
t1.join()
t2.join()
print("--1--")
输出结果为:
正在唱歌
正在跳舞
正在唱歌
正在跳舞
正在唱歌
正在跳舞
--1--
查看线程数量
使用threading.enumerate()来查看当前线程的数量。
import time
import threading
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()
while True:
print(threading.enumerate())
if len(threading.enumerate()) <= 1:
break
time.sleep(1)
# main()
if __name__ == '__main__':
main()
**#线程运行的时候,没有先后顺序,多次运行会有细微的差别。**
4.0验证子线程的创建与执行
import threading #多线程
import time
def demo1():
for i in range(3):
print("---demo1---")
time.sleep(1)
def mian():
print(threading.enumerate())
t1 = threading.Thread(target=demo1)
print(threading.enumerate())
#创建子线程,执行子线程
t1.start()
print(threading.enumerate())
if __name__ == '__main__':
mian()
执行结果:
[<_MainThread(MainThread, started 12308)>]
[<_MainThread(MainThread, started 12308)>]
---demo1---
[<_MainThread(MainThread, started 12308)>, <Thread(Thread-1, started 9304)>]
---demo1---
---demo1---
5.0 继承Thread类创建线程
**方法一:**
import threading
import time
class A(threading.Thread):
def run(self):
for i in range(3):
print("demo1")
time.sleep(1)
class B(threading.Thread):
def ru(self):
for i in range(3):
print("demo2")
time.sleep(1)
if __name__ == '__main__':
t1 = threading.Thread(target=A().run)
t2 = threading.Thread(target=B().ru)
t1.start()
t2.start()
方法二:
import threading
import time
#1.继承Thread类
class A(threading.Thread):
#2 在类的内部重写run方法,只能是run方法
def run(self):
for i in range(3):
print("demo1")
time.sleep(1)
class B(threading.Thread):
def run(self):
for i in range(3):
print("demo2")
time.sleep(1)
if __name__ == '__main__':
#3.实例化类
t1 = A()
t2 = B()
print(threading.enumerate())
t1.start()
t2.start()
print(threading.enumerate())
‘’‘
###效果同上,如果类中有其他线程,在run中直接调用
import threading
import time
class A(threading.Thread):
def run(self):
for i in range(3):
print("demo1")
self.demo2()
time.sleep(1)
def demo2(self):
print("demo2")
if __name__ == '__main__':
t1 = A()
t1.start()
’‘’
6.0多线程共享全局变量
实例一普通情况:
num = 100
def demo1():
global num
num += 1
print(f"demo1---{num}")
def demo2():
print(f"demo2---{num}")
print(num)
demo1()
demo2()
打印的结果为:
100
demo1---101
demo2---101
实例二 多线程全局变量:
#线程中共享全局变量
import threading
import time
num = 100
def demo1():
global num
num += 1
print(f"demo1---{num}")
time.sleep(1)
def demo2():
print(f"demo2---{num}")
time.sleep(1)
def mian():
t1 = threading.Thread(target=demo1)
t2 = threading.Thread(target=demo2)
t1.start()
time.sleep(1)
t2.start()
time.sleep(1)
print(f"主线程Thread -----{num}")
print(threading.enumerate())
if __name__ == '__main__':
mian()
打印结果为:
demo1---101
demo2---101
主线程Thread -----101
[<_MainThread(MainThread, started 7104)>, <Thread(Thread-2, started 11504)>]
7.0 多线程之间传参
import threading
import time
num = [1, 2]
def demo1(num1):
num1.append(3)
print(f"demo1---{num1}")
def demo2(num):
print(f"demo2---{num}")
if __name__ == '__main__':
t1 = threading.Thread(target=demo1, kwargs={"num1":[3,4]}) #添加字典参数
t2 = threading.Thread(target=demo2, args=(num,)) #添加元组参数
t1.start()
t2.start()