多线程的创建
import threading def func(arg): print(arg) t1 = threading.Thread(target=func,args=(333,)) #创建一个线程t1, args后跟的是一个元组 t1.start() t2 = threading.Thread(target=func,args=(111,)) #创建一个线程t1 t2.start()
线程的基本使用
import threading def func(arg): print(arg) t = threading.Thread(target=func,args=(123,)) t.start() print(1111) # 结果: # 123 # 1111
线程的本质
import threading def func(arg): print(arg) t1 = threading.Thread(target=func,args=(111,)) t1.start() #start 是开始运行线程吗? 不是的. 主要是告诉CPU,已经准备就绪,可以调用 print(123) 先打印111 还是先打印123 不确定 如果一个进程下面有3个线程, 一个是主线程 111, 一个是子线程123, cpu正在执行第三个线程 这就很难判断cpu 下一步是执行111, 还是123, 从打印的结果看不出来的
主线程默认等子线程执行完毕
import threading import time def func(arg): time.sleep(arg) print(arg) t1 = threading.Thread(target=func,args=(2,)) t1.start() t2 = threading.Thread(target=func,args=(4,)) t2.start() print(1234) # 结果 # 1234 # 2 # 4
主线程不等待子线程的情况, 主线程执行完毕后, 子线程就停止
import time import threading def func(arg): time.sleep(arg) print(arg)
t1 = threading.Thread(target=func,args=(4,)) t1.setDaemon(True) # True 主线程 执行完毕不等 子线程 t1.start() t2 = threading.Thread(target=func,args=(2,)) t2.setDaemon(False) # False 主线程等待子线程执行完毕
# 线程2 如果停顿时间比 线程1 短的时候,就会只执行 线程2 t2.start() print(1111111) # 结果 # 1111111 # 2
def func(arg): time.sleep(arg) print(arg) t1 = threading.Thread(target=func,args=(4,)) t1.setDaemon(True) # True 主线程 执行完毕不等 子线程 t1 t1.start() t2 = threading.Thread(target=func,args=(6,)) t2.setDaemon(False) # False 主线程等待子线t2 程执行完毕
#线程2如果停顿时间参数arg比线程1的时间长,在等待t2的时候,线程t1还在运行,所以t1还是会被打印
t2.start() print(1111111) # 结果 # 1111111 # 4 # 6
开发人员可以控制主线程等待子线程的时间(最长等待时间)
import threading import time def func(arg): time.sleep(2) print(arg) print("创建子线程t1") t1 = threading.Thread(target=func,args=(3,)) t1.start() t1.join() #无参数,让主线程在这里等待,等子线程t1执行完毕后,才可以继续往下走 # t1.join(2) #有参数,让主线程在这里最多停留n 秒,无论是否执行完毕都会继续往下走 print("创建子线程t2") t2 = threading.Thread(target=func,args=(6,)) t2.start() t2.join(1) #让主线程在这等1秒后才打印1234, 如果子线程睡了0.5秒, 就只等待0.5秒. 1是最多等待1秒
print(1234)
#结果
创建子线程t1
3
创建子线程t2
1234
6
获取线程的名称
import threading def func(arg): # 获取当前执行该函数的线程对象 t = threading.current_thread() # 根据当前线程对象获取当前线程名称 name = t.getName() print(name,arg) t1 = threading.Thread(target=func,args=(11,)) t1.setName("王小二") t1.start() t2 = threading.Thread(target=func,args=(22,)) t2.setName("张三") t2.start() print(1234) # 王小二 11 # 张三 22 # 1234
GIL全局解释器锁
python内置的一个全局解释器锁,同一时刻的进程中,只有一个线程被cpu调用.
也可以这么理解,
软件就是一个进程(宫殿), 进程就创建一个空间(宫殿), 进程里面可以有多个线程(妃子)
GIL锁限制一个进程(宫殿)中只有一个线程(妃子),可以被cpu(皇上)调用
如果一个进程里面有多个线程,cpu就会在多个线程之间来回调用,执行的速度很快,人感觉不到停顿.
但是中间到底停留了多久呢?
import sys v1 = sys.getcheckinterval() print(v1) #100
默认GIL锁使得每一线程处理100个cpu指令以后,会切换到下一个线程
GIL锁(全局解释器锁),限制一个进程(宫殿)中只有一个线程(妃子), 可以被CPU(皇上)调用