6. 线程
0.大纲
线程的介绍;
多线程完成多任务:多线程步骤、无参线程、有参线程;
线程的注意点:执行顺序、共享全局变量、数据安全;
互斥锁的使用:api使用步骤、死锁;
进程与线程随笔;
1. 线程创建步骤:
| 步骤 | 说明 |
|---|---|
| 第一步:导包 | import threading |
| 第二步:通过线程类创建线程对象 | 线程名=threading.Thread(target=函数名) |
| 第三步:启动线程执行任务 | 线程名.start() |
图示和代码实现:无参函数和带参函数
""" 案例:演示多线程 -- 不带参数(即任务函数不带参数) 实现步骤: 1.导包 2.创建线程对象 3.启动线程 """# 1.导包importthreadingimporttime# 2.定义函数,表示 敲代码defcoding():foriinrange(1,11):time.sleep(0.1)print(f"正在敲第{i}遍代码...")# 2.定义函数,表示 听音乐defmusic():foriinrange(1,11):time.sleep(0.1)print(f"正在听第{i}遍音乐...")# 3.测试if__name__=='__main__':# 4.创建两个线程对象,分别关联上述两个目标函数p1=threading.Thread(target=coding)p2=threading.Thread(target=music)# 4.启动线程p1.start()p2.start()""" 案例:演示多线程 -- 带参数(即任务函数带参数) 实现步骤: 1.导包 2.创建线程对象 3.启动线程 """# 1.导包importthreadingimporttime# 2.定义函数,表示 敲代码defcoding(name,num):foriinrange(1,num+1):time.sleep(0.1)print(f"{name}正在敲第{i}遍代码...")# 2.定义函数,表示 听音乐defmusic(name,count):foriinrange(1,count+1):time.sleep(0.1)print(f"{name}正在听第{i}遍音乐...")# 3.测试if__name__=='__main__':# 4.创建两个线程对象,分别关联上述两个目标函数p1=threading.Thread(target=coding,args=('小明',10))p2=threading.Thread(target=music,kwargs={'count':20,'name':'小王'})# 4.启动线程p1.start()p2.start()2. 线程注意点:
① 线程之间的执行是无序的:线程执行具有随机性,原因是CPU在做着高效的切换;(随机性)
② 主线程会等待所有的子线程执行结束再结束:可以通过设置守护线程实现。守护主线程即主线程退出子线程销毁不再执行,实现:threading.Thread(target=函数名, daemon= True);(守护线程)
③(同一进程的)线程间 数据共享;(数据共享)
④ 多线程操作共享数据,可能会出现安全问题,可以用 互斥锁解决。
代码示例:
""" 案例:演示多线程特点 -- 随机性 """# 导包importthreadingimporttime# 1.定义线程的目标函数defprint_info():# 1.1 休眠time.sleep(0.2)# 1.2 获取当前线程对象current_thread=threading.current_thread()# 1.3 打印线程名称print(current_thread.name)# 2.测试if__name__=='__main__':# 2.1 创建10个线程,观察执行顺序foriinrange(10):t=threading.Thread(target=print_info)t.start()""" 案例:演示多线程特点 -- 守护线程 """# 导包importthreading,time# 1.定义线程的目标函数defwork():foriinrange(10):time.sleep(0.2)print("工作中....")# 2.测试if__name__=='__main__':# 2.1 创建子线程# 方式一:创建时添加属性'daemon=True'# t=threading.Thread(target=work, daemon=True)# 方式二:创建完之后设置属性't.daemon=True't=threading.Thread(target=work)t.daemon=True# 2.2 启动线程t.start()# 2.3 设置主线程休眠时间time.sleep(1)""" 案例:演示多线程特点 -- 数据共享 """#需求:定义全局变量my_list=[],定义两个目标函数分别实现添加、查看数据。# 最后创建两个线程,分别执行对应的任务,观察结果。# 导包importthreading,time# 1.定义全局变量my_list=[]# 2.定义线程的目标函数1:添加数据defwrite_data():foriinrange(1,4):my_list.append(i)print("添加数据:",i)print(f'write_data:{my_list}')# 2.定义线程的目标函数2:查看数据defread_data():time.sleep(2)print(f'read_data:{my_list}')# 3.测试if__name__=='__main__':# 3.1 创建线程并启动threading.Thread(target=write_data).start()threading.Thread(target=read_data).start()# 运行结果:# 添加数据: 1# 添加数据: 2# 添加数据: 3# write_data:[1, 2, 3]# read_data:[1, 2, 3]