线程
线程被称作轻量级的进程。 GIL:全局解释锁(只有Cpython解释器才有) 线程会被强迫放弃CPU的因素 (线程会受时间片影响)(GIL会限制每个线程的执行时间,一般是5毫秒)(或者限制线程执行固定数量的字节码) 对于线程来说,因为有了GIL,所以没有真正的并行 计算机的执行单位以线程为单位。计算机的最小可执行是线程。 进程是资源分配的基本单位。线程是可执行的基本单位,是可被调度的基本单位。 线程不可以自己独立拥有资源。线程的执行,必须依赖于所属进程中的资源。 进程中必须至少应该有一个线程。 线程又分为用户级线程和内核级线程(了解) 用户级线程:对于程序员来说的,这样的线程完全被程序员控制执行,调度 内核级线程:对于计算机内核来说的,这样的线程完全被内核控制调度。 进程由 代码段 数据段 PCB组成(process control block) 线程由 代码段 数据段 TCB组成(thread control block) #模块:threading #导入方法:from threading import Thread #线程和进程的比较 thread - 线程 import thread 操作线程的模块 import threading 用这个去操作线程 (1) cpu切换进程要比cpu切换线程 慢很多 在python中,如果IO操作过多的话,使用多线程最好了 (2) 在同一个进程内,所有线程共享这个进程的pid,也就是说所有线程共享所属进程的所有资源和内存地址 (3) 在同一个进程内,所有线程共享该进程中的全局变量 (4) 因为有GIL锁的存在,在Cpython中,没有真正的线程并行。但是有真正的多进程并行 当你的任务是计算密集的情况下,使用多进程好 总结:在CPython中,IO密集用多线程,计算密集用多进程 (5)关于守护线程和守护进程的事情(注意:代码执行结束并不代表程序结束) 守护进程:要么自己正常结束,要么根据父进程的代码执行结束而结束 守护线程:要么自己正常结束,要么根据父线程的执行结束而结束 #线程方法: (1)锁机制 递归锁 RLock() 可以有无止尽的锁,但是会有一把万能钥匙 互斥锁: Lock() 一把钥匙配一把锁 GIL:全局解释器锁 锁的是线程,是CPython解释器上的一个锁,锁的是线程,意思是在同一时间只允许一个线程访问cpu (2) 信号量: from threading import Semaphore 去看多进程的信号量 (3) 事件 from threading import Event 去看多进程的事件机制 (4) 条件 from threading import Condition 条件是让程序员自行去调度线程的一个机制 # Condition涉及4个方法 # acquire() # release() # wait() 是指让线程阻塞住 # notify(int) 是指给wait发一个信号,让wait变成不阻塞 # int是指,你要给多少给wait发信号 (5) 定时器 from threading import Timer # Timer(time,func) # time:睡眠的时间,以秒为单位 # func:睡眠时间之后,需要执行的任务 #基本使用方法: import threading from threading import Thread import time ################################# 常规方法 # def func(): # print('这是一个子线程') # time.sleep(2) # # if __name__ == '__main__': # t = Thread(target=func,args=()) # t.start() #################################类的方法 # class MyThread(Thread): # def __init__(self): # super(MyThread, self).__init__() # def run(self): # print('我是一个子线程') # # t = MyThread() # t.start()
模块:Condition 导入方法:from threading import Condition,Thread 模块方法:con=Condition() #con.acquire() #con.release() #con.wait() # 假设有一个初始状态为False,阻塞。一旦接受到notify的信号后,变为True,不再阻塞 #con.notify(int) 给wait发信号,发int个信号,会传递给int个wait,让int个线程正常执行 注意事项: 同一个线程内,递归锁可以多次acquire,但互斥锁不可以 不同线程,递归锁是保证只能一个线程用,并多次acquire,其他线程等待 #例子 from threading import Condition,Thread import time def func(con,i): con.acquire()# 主线程和10个子线程都在抢夺递归锁的一把钥匙。 # 如果主线程抢到钥匙,主线程执行while 1,input,然后notify发信号,还钥匙。但是,此时如果主线程执行特别快 # 极有可能接下来主线程又会拿到钥匙,那么此时哪怕其他10个子线程的wait接收到信号,但是因为没有拿到钥匙,所以其他子线程还是不会执行 con.wait() print('第%s个线程执行了'%i) con.release() con = Condition() for i in range(10): t = Thread(target=func,args = (con,i)) t.start() while 1: # print(123) con.acquire() num = input('>>>') con.notify(int(num)) con.release() time.sleep(0.5)