线程
线程与进程的关系
1,一个进程至少会有一个进程
2,线程是不能独立存在的
线程与进程的区别
1,进程是计算机的最小资源分配单位
2,线程是cpu的最小调度单位
3,进程之间的数据是隔离的
4,同一个进程内的的线程直接的数据是共享的
GIL锁,全局解释器锁,全局锁
cpython才会有
同一个进程内在同一个时刻只有有个线程会被CPU调度
在多I/O阻塞的程序中,用多线程
在高计算的程序中,用多进程
线程直接的数据是共享的
1 from threading import Thread 2 import time 3 n=100 4 def func(): 5 global n 6 n=n-1 7 t=Thread(target=func).start() 8 time.sleep(1) 9 print(n) 10 #99
守护线程
守护线程与守护进程
守护进程 守护进程会随主进程代码的结束而结束(程序的报活)
守护线程 主线程在结束之后,会等待子线程的结束而结束
主线程的结束,就意味着主进程的结束
1 from threading import Thread 2 def func(): 3 print("守护线程") 4 def func1(): 5 print("子线程") 6 t=Thread(target=func) 7 t1=Thread(target=func1) 8 t.daemon=True 9 t.start() 10 t1.start() 11 print("主进程") 12 守护线程 13 子线程 14 主进程
互斥锁与递归锁
为什么线程中有GIL锁,还要有锁?
当在进行 +=,-= 的时候,会数据不安全(要进行取值,计算,赋值三步操作,有可能在做完取值,计算之后就时间片轮转,这时候就没办法赋值,另外的
的线程就继续取值)
列表的append,pop操作,队列,logging模块的数据是安全的
递归锁
当一个线程在得到一把锁之后,还需要得到另一把锁
一个线程的到了一把锁,另一把锁被另外一个线程的到了,就会发生死锁
递归锁是解决死锁最快的方法,但不是最好的方法,还是要慢慢换用互斥锁
出现死锁不是互斥锁的原因,而是程序员编码时的逻辑问题
信号量
信号量是计数器和锁来实现的
1 from threading import Thread,Semaphore 2 import time 3 def func(s): 4 s.acquire() 5 time.sleep(1) 6 print("hello") 7 s.release() 8 s=Semaphore(3) 9 for i in range(10): 10 t=Thread(target=func,args=(s,)).start()
事件
e=Event()
e.wait() 如果e.is_set==False将阻塞线程
e.set() 设置event的值为True
e.clear 恢复event的值为False
e.is_set() 返回event的状态值
1 from threading import Thread,Event 2 import time 3 def check(e): 4 print("开始检测数据库连接") 5 time.sleep(2) 6 e.set() 7 def connect(e): 8 time.sleep(1) 9 for i in range(3): 10 e.wait(1) 11 if e.is_set(): 12 print("数据库连接成功") 13 break 14 else:print('第{}次数据库连接失败'.format(i+1)) 15 e=Event() 16 t=Thread(target=connect,args=(e,)).start() 17 t1=Thread(target=check,args=(e,)).start()
条件
wait()
notify()
wait和notify必须在acquire和release中间使用
1 eading import Thread,Condition 2 def func(con,name): 3 print("{}等待中".format(name)) 4 con.acquire() 5 con.wait() 6 print("{}在游戏中".format(name)) 7 con.release() 8 con=Condition() 9 for i in range(20): 10 t=Thread(target=func,args=(con,i)) 11 t.start() 12 con.acquire() 13 con.notify(3) 14 con.release()
定时器
1 from threading import Timer 2 def func(): 3 print("666") 4 t=Timer(3,func).start()
队列
Queue 先进先出
LifoQueue 栈,后进先出
PriorityQueue 优先级队列