线程02-并发串行-互斥锁-Semaphore-Event

并行和串行线程

  1. 并发线程:主线程创建线程1,立即返回;创建线程2,立即返回。两个子线程各自执行 run,几乎同时打印 start,然后 sleep 1,然后几乎同时打印 done;---于是完成并行操作。
python 复制代码
import threading,time

def run(n):
    print("task start: ",n)
    time.sleep(1)
    print("task done: ",n)

start_time=time.time()
t1=threading.Thread(target=run,args=("t1",))
t2=threading.Thread(target=run,args=("t2",))
#并发进行
t1.start()
t2.start()

time.sleep(2)
print("cost time:", time.time()-start_time)
  1. 串行线程:主线程调用 t1.run -> task start t1 -> sleep 1 -> task done t1,接着调用t2.run -> task start t2 -> sleep 1 -> task done t2----于是完成串行操作;
python 复制代码
import threading,time

def run(n):
    print("task start: ",n)
    time.sleep(1)
    print("task done: ",n)

start_time=time.time()
t1=threading.Thread(target=run,args=("t1",))
t2=threading.Thread(target=run,args=("t2",))
#调用run函数,串行进行
t1.run()
t2.run()

time.sleep(2)
print("cost time:", time.time()-start_time)

测试结果:

等待线程完成

  1. 50个线程等待完成。通过两个循环实现线程完成。如果没有join()方法,只能看到线程开始执行;
python 复制代码
import threading,time

def run(n):
    print("task start: ",n)
    time.sleep(1)
    print("task done: ",n)

start_time=time.time()  #线程开始时间
t_list=[]  #启动的线程空列表
for x in range(50):
    t=threading.Thread(target=run,args=("t-{}".format(x+1),))
    t.start()
    t_list.append(t) #将每一个启动的线程加入list

for y in t_list:
    y.join()  #循环等待每个线程完成

time.sleep(1)
print("===waiting threading finish===",threading.current_thread())#当前完成的是主线程
print("cost time:", time.time()-start_time)  #所有线程消耗时间

测试结果

线程锁-互斥锁--加了锁的多线程

  1. 线程执行过程中,先获取锁然后执行该线程,执行完成后才能释放锁---这样就完成了互斥锁(只是小范围区域顺序执行,锁之外的线程依然是并行执行)
  2. 和run的区别:
    • run都是串行,加锁的多线程锁住的部分串行,其他并行,
    • run没有创建子线程只有一个主线程,加锁的多线程他创建子线程;
python 复制代码
import threading,time

lock=threading.Lock()#锁的实例化
def run(n):
    print("task start: ", n)

    global num
    lock.acquire() #获取锁
    num += 1
    lock.release()#释放锁

    time.sleep(1)
    print("task done: ", n)

num=0
t_list=[]  #启动的线程空列表
for x in range(10):
    t=threading.Thread(target=run,args=("t-{}".format(x+1),))
    t.start()
    t_list.append(t) #将每一个启动的线程加入list

for y in t_list:
    y.join()  #循环等待每个线程完成

time.sleep(1)
print("===waiting threading finish===",threading.current_thread())#当前完成的是主线程
print("num is ",num)

测试结果

Semaphore

  1. Semaphore允许多个线程同时进入,但数量有限制。threading.Semaphore 是一个计数器信号量;
  2. Semaphore 控制的是同时进入的线程数量,不是让线程串行;
python 复制代码
import threading,time

semaphore =threading.BoundedSemaphore(3)  #最多允许 3 个线程同时进入临界区
def run(n):
    with semaphore:  #使用with避免忘记释放锁
    time.sleep(1)
    print("run the thread:{}".format(n))
    
t_list=[]
num=0
for x in range(10):  #启动10个线程
    t=threading.Thread(target=run,args=(x,))
    t.start()
    num +=1
    t_list.append(t)

for t in t_list:  #循环执行线程
    t.join()
    
print("end")
print(num)

测试结果:

Event

  1. 事件:threading.Event() 是一个简单的线程间通信机制,维护一个内部标志,set() 设为 True,clear() 设为 False,wait() 阻塞直到标志为 True,is_set() 检查标志;
python 复制代码
import threading,time

event=threading.Event() #实例化事件,两个事件
def light():
    count=0
    event.set()  #初始化为绿灯
    while True:
        if count>4 and count<=9: #红灯  count = 5~9:红灯,event 被 clear(),变成 False
            event.clear()
            print("\033[41;1mred light is on...\033[0m")
        elif count>9:  count = 10:进入 elif,event.set() 变绿灯,count 重置为 0
            event.set()  #变绿灯
            count=0
            print("\033[42;1mgreen light is on...\033[0m")
        else:  #count = 0~4:绿灯,event 为 True
            print("\033[42;1mgreen light is on...\033[0m")
        time.sleep(1)
        count += 1
        
#绿灯就跑,红灯就等
def car(name):
    while True:
        if event.is_set():  # 绿灯
            print("[%s] running..."%name)
            time.sleep(1)
        else:   #红灯
            print("[%s]sees red light,waiting..."%name)
            event.wait()  #等待标记位设置
            print("[%s] green light is on,start going..."%name)


light=threading.Thread(target=light,)
light.daemon = True  # 设为守护线程,主线程结束就退出
light.start()

car1=threading.Thread(target=car,args=("奔驰",))
car1.daemon = True
car1.start()
相关推荐
特立独行的猫A3 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
大可不必了7 小时前
03 函数定义和调用
开发语言·python
承渊政道8 小时前
【Python编程—从入门到实践】(记分与闯关:用Python+Pygame,打造越战越精彩的太空大战!)
开发语言·python·pycharm·游戏程序·pygame
爱学习的程序媛8 小时前
Python常用框架梳理
开发语言·后端·python·ai·web·后端框架·python框架
imgsq8 小时前
GESP Python 一到四级:备考路线与真题特点
python·青少年编程
eggwyw10 小时前
Anaconda安装卸载的详细流程指南
开发语言·python
2601_9679791210 小时前
纯手写:Python安装pip完整教程,搞了几小时,终于成功
python·教程·pip·安装·包管理
Norna10 小时前
缓存文件从没写出来:一个 .json 被当成目录用了
python
aifannihao13 小时前
AI 学习第 14 课:CNN 训 6 轮卡在 0.5352,数据没打乱
pytorch·python·深度学习·cnn·学习路线
yuyuxun113 小时前
协同过滤的校园二手物品智能推荐系统的设计与实现 毕业设计-附源码40082
javascript·vue.js·spring boot·python·数据分析·django·课程设计