多线程
优点
使用线程可以把占据长时间的程序中的任务放到后台去处理。
用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
程序的运行速度可能加快
在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
线程和进程
线程在执行过程中与进程还是有区别的。每个独立的进程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。
线程可以被抢占(中断)。
在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。
线程模块
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名
创建线程
方式一:函数创建线程
import threading import time # 自定义线程函数 def test(x): print(x) time.sleep(3) # 设置隔两秒打印一个x # 创建线程t1,指定参数为1 t1 = threading.Thread(target=test, args=(1,)) # 创建线程t2,指定参数为2 t2 = threading.Thread(target=test, args=(2,)) start_time = time.time() t1.start()# 启动线程t1 t2.start()# 启动线程t2 print(f"共运行了{time.time() - start_time}秒")
输出:
1
2
共运行了0.0019960403442382812秒
方式二:类创建线程
#用类创建线程,继承threading.Thread
class MyThread(threading.Thread):
def __init__(self,n):
super(MyThread,self).__init__()
self.n = n
#重写run方法
def run(self):
print("以类的方式创建多线程",self.n)
r1 = MyThread(11)
r2 = MyThread(22)
start_time = time.time()
r1.start()
r2.start()
print(f"共运行了{time.time()-start_time}秒")
输出:
以类的方式创建多线程 11
以类的方式创建多线程 22共运行了0.001999378204345703秒
线程锁
def run():
global x #设置全体变量
lock.acquire() #操作变量之前进行加锁
x += 1
lock.release() #操作变量之后进行解锁if __name__ == '__main__':
x = 0 #定义变量x
res = [] #定义列表
lock = threading.Lock() #实例化一个锁对象
#创建多线程
for i in range(100):
t = threading.Thread(target=run)
t.start()
res.append(t) #写入列表
for t in res:
t.join()
print(x
递归锁
"""递归锁"""
import threading
def run1():
global x
lock.acquire() # 操作变量之前进行加锁
x += 1
lock.release() # 操作变量之后进行解锁
return xdef run2():
global y
lock.acquire() # 操作变量之前进行加锁
y += 1lock.release() # 操作变量之后进行解锁
return ydef run3():
lock.acquire() # 操作变量之前进行加锁
res1 = run1()
res2 = run2()
lock.release() # 操作变量之后进行解锁
print(res1,res2)if __name__ == '__main__':
x = 0
y = 0
lock = threading.RLock() #实例化一个锁对象
for i in range(50):
t = threading.Thread(target=run3)
t.start()while threading.active_count() != 1:
print(f'正在运行{threading.active_count()}个线程')
print('线程运行结束!')
输出:
仅为学习笔记!!!!
原视频请看
python语言爱好者的个人空间_哔哩哔哩_bilibili