一、多任务-线程
1、介绍
多任务:同一时间,多个任务同时执行
windows是多任务,python默认是单任务
2、线程的基本使用
线程是被系统独立调度和分派的基本单位
主线程:
当一个程序启动时,就有一个进程被操作系统创建,于此同时一个线程也立刻运行,这就叫做程序的主线程。 程序启动就会创建一个主线程
主线程的作用:
1、可以产生其他的子线程 2、它必须最后完成执行,比如执行各种关闭动作
子线程:
可以看做是程序执行的一条分支,当子线程启动后会和主线程一起同时执行
3、使用threading模块创建子进程
1、核心方法
threading.Thread(target=函数名),threading模块的Thread类创建子进程对象 线程对象.start()启动子进程
"""
子线程创建的步骤
1、导入模块
2、使用threading.Thread()创建对象(子进程对象)
3、指定子线程执行的分支
4、启动子线程,线程对象.start()
"""
import time
import threading
def SaySorry():
print("sorry,i am wrong")
time.sleep(0.5)
if __name__ == '__main__':
for i in range(5):
thread_obj = threading.Thread(target=SaySorry)
thread_obj.start()
多线程的优点就是更加快了,因为同一个任务有更多的线程在进行
4、线程的名称及总数量
4.1 查看线程数量
threading.enumerate()可以获取当前所有活跃的线程对象列表,使用len()可以看到活跃的线程个数
import threading
import time
def sing():
for i in range(5):
print("正在唱歌...")
time.sleep(0.5)
def dance():
for i in range(5):
print("正在跳舞...")
time.sleep(0.5)
if __name__ == '__main__':
thread_list=threading.enumerate()
print("当前线程数量为:",len(thread_list))
thread_sing=threading.Thread(target=sing)
thread_dance = threading.Thread(target=dance)
thread_sing.start()
thread_dance.start()
thread_list = threading.enumerate()
print("当前线程数量为:",len(thread_list))
结果为:
当前线程数量为: 1
正在唱歌...
正在跳舞...
当前线程数量为: 3
正在跳舞...正在唱歌...
正在跳舞...正在唱歌...
正在唱歌...正在跳舞...
正在唱歌...
正在跳舞...
4.2 查看线程名称
threading.current_thread()显示的是当前的线程对象
在上述代码上做如下改动:
...
def sing():
for i in range(5):
print("正在唱歌...",threading.current_thread())
time.sleep(0.5)
def dance():
for i in range(5):
print("正在跳舞...",threading.current_thread())
time.sleep(0.5)
if __name__ == '__main__':
print(threading.current_thread())
...
结果如下,我们可以看到线程的名称,有两个子线程:
5、线参数及顺序
目标:
1、能够向线程函数传递多个参数 2、能够说出多线程执行的顺序特点
传递参数的方式有三种:
1、使用元组–args=(参数1,参数2) 2、使用字典–kwargs={“参数名”:参数值…} 3、混合使用元组和字典
import threading
import time
def sing(a,b,c):
print("参数为:",a,b,c)
for i in range(5):
print("正在唱歌...")
time.sleep(0.5)
def dance():
for i in range(5):
print("正在跳舞...")
time.sleep(0.5)
if __name__ == '__main__':
thread_sing=threading.Thread(target=sing,args=(10,100,1000))
thread_sing = threading.Thread(target=sing, kwargs={"a":100,"b":90,"c":40})
thread_sing = threading.Thread(target=sing, args=(20,),kwargs={"b":90,"c":40})
thread_dance = threading.Thread(target=dance)
thread_sing.start()
thread_dance.start()
线程的执行顺序是无序的,线程由cpu调度执行,cpu根据系统的运行状态,按照自己的调度算法去调度执行
6、守护线程
目标:
能够使用setDaemon设置子线程守护主线程
什么是守护线程:
如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出(主线程挂,子线程也得挂),设置方式为thread.setDaemon(True),要在thread.start()之前设置,默认是False的(也就是主线程结束时,子线程仍然在执行)
默认的情况
import threading
import time
def work():
for i in range(10):
print("正在执行work1...",i)
time.sleep(0.5)
if __name__ == '__main__':
thread_obj=threading.Thread(target=work)
thread_obj.start()
time.sleep(2)
print("Game Over")
exit()
结果为: 主线程都已经挂了,子线程还在进行,这是不可取的,所以我们设置守护线程
import threading
import time
def work():
for i in range(10):
print("正在执行work1...",i)
time.sleep(0.5)
if __name__ == '__main__':
thread_obj=threading.Thread(target=work)
thread_obj.setDaemon(True)
thread_obj.start()
time.sleep(2)
print("Game Over")
exit()
结果为:
7、并行和并发
目标:
能够说出并行和并发的区别
并发:
任务数大于cpu核数,任务1,2,3需要轮询处理
并行:
任务数小于等于cpu核数,任务真的是一起执行的,任务1和任务2不需要轮询
|