三十七、线程(重点):创建线程、线程共享全局变量、互斥锁(知道原理)
一、创建线程
(1)线程导包的两种方式:
(2)
1、多个线程执行同一个函数,线程之间互不影响,并且主线程与子线程之间也互不影响,各自执行各自的代码
2、进程里面包含线程 —— 进程是资源分配的单位,线程是CPU调度的单位。
进程,能够完成多任务,比如 在一台电脑上能够同时运行多个QQ
线程,能够完成多任务,比如 一个QQ中的多个聊天窗口
3、主线程会等待所有的子线程结束后才结束
(3)使用方法创建线程:
(4)使用类创建线程:
二、线程共享全局变量、互斥锁
(1)
1、对于多线程而言,对全局变量是共享的,而对于多进程来说,对全局变量是不共享的,可以用队列实现进程间通信。
2、多线程开发中,全局变量是多个线程都共享的数据,而局部变量等是各自线程的,互不干扰,是非共享的。
(2)
线程优点:可以共享全局变量
缺点: 用不好,易发生错乱现象(3种解决方案)
(3) 列表可当做实参传递到线程处理函数中
(4)Python中实现多任务的三种方式:进程、线程、协程
(5)综合实例:由于线程用不好会错乱,解决方法3种:
1、解决方法1(最简单):
让预想的任务先执行完以后,可以使用time.sleep(2),让其睡2秒,等上个任务执行完毕,再执行下个线程,就不会错乱。
2、解决方法2: 再定义个全局变量 g_flag=1,用if条件判断
g_flag这个全局变量的作用:它是一种标志,如果值为1说明,任务test1还没有执行完;
如果值为0说明,任务test1执行完了。
3、解决方法3: 互斥锁(知道用法,原理)
1、mutex不固定,可自己定义
2、from threading import Thread,Lock这种形式的导包,创建锁:mutex = Lock()
3、import threading 这种形式的导包,创建锁:mutex=threading.Lock()
4、mutex = acquire() 锁定、默认上锁
5、mutex = release() 解锁、释放
注意:
① 最好创建一个锁(靠谱不乱),每个函数下都要写上锁定、解锁命令,不然执行结果不对
② 有了互斥锁后,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
③ 一把锁的话,只能把锁内的内容执行完后,解锁后,再执行下个任务。(循环多的话,还是一把锁靠谱)
④ 容易形成死锁,写程序时,要逻辑清晰,要避免死锁