Python_03(多线程)

多线程

优点

使用线程可以把占据长时间的程序中的任务放到后台去处理。

用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度

程序的运行速度可能加快

在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

线程和进程

线程在执行过程中与进程还是有区别的。每个独立的进程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

每个线程都有他自己的一组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 x

def run2():
    global y
    lock.acquire()  # 操作变量之前进行加锁
    y += 1

    lock.release()  # 操作变量之后进行解锁
    return y

def 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_03(多线程)

仅为学习笔记!!!!

原视频请看

python语言爱好者的个人空间_哔哩哔哩_bilibili 

上一篇:Python—多线程


下一篇:【Python】高级培训多线程学习