多线程
也是实现多任务的方式。thread是比较底层的模块,threading模块对其进行包装,更方便被使用。
threading 单线程
进程 资源分配的单位,内存等资源
线程 进程里面真正执行代码的东西,CPU调度的单位
如果多个线程执行的都是同一个函数的话,各自之间不会有影响,各是各的
线程的执行顺序
也是根据调度算法,不确定执行顺序
进程之间不共享数据,所以产生进程间通信,队列等,线程之间共享全局变量
多线程开发可能存在的问题(100万问题)
from threading import Thread
import time
g_num = 0
def test1():
global g_num
for i in range(1000000):
g_num += 1
print("---test1---g_num=%d"%g_num)
def test2():
global g_num
for i in range(1000000):
g_num += 1
print("---test2---g_num=%d"%g_num)
p1 = Thread(target=test1)
p1.start()
# time.sleep(3) #取消屏蔽之后 再次运⾏程序, 结果会不⼀样, , , 为啥呢?
p2 = Thread(target=test2)
p2.start()
print("---g_num=%d---"%g_num)
问题产⽣的原因就是没有控制多个线程对同⼀资源的访问, 对数据造成破
坏, 使得线程运⾏的结果不可预期。 这种现象称为“线程不安全”。
列表当参数传进去,也会是在多线程之间共享
同步
原子性,要不就不动,要不就整完全。
避免全局变量被修改的方式 (如何解决100万次的问题)
轮询,占CPU,效率不高,一直得盯着。
互斥锁
很好的解决这个问题,
等待解锁的机制 通知机制,发消息
非全局变量,也就是函数里面的变量,不需要加锁
死锁
解决死锁的方法 添加超时时间,或程序设计时尽量避免(银行家算法)
同步
多方一起协同执行的时候,协同步调,按预定的先后次序进行运行。比如演讲顺序
如果不确定顺序,就是异步
堵塞和非堵塞
程序执行的时候,等还是不等
多个互斥锁让多个线程有序执行
生产者和消费者模式解决耦合问题
多任务,一方产生数据,一方处理数据,速度不匹配。用Queue队列
队列 先进先出 FIFO
栈 先进后出 LIFO
ThreadLocal全局变量
异步的实现
正在做一件事,不确定什么时候会再做另一件事,就是异步
GIL 全局解释器锁
python语言中的多线程是假的,而多进程效率最高
如果需要多线程,用C语言写死循环的部分,解决GIL问题。