线程被称作轻量级的进程。 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)
知识兔