线程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()
相关推荐
程序猿乐锅11 分钟前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
lzqrzpt13 分钟前
太阳能控制器选型要点:电路工艺与工程适配技术解析
python·1024程序员节
databook1 小时前
时间序列数据中,如何找出缺失值
python·数据分析
小小龙学IT2 小时前
Python Polars 高性能数据处理引擎深度解析
开发语言·python·rust·1024程序员节
csdn_aspnet2 小时前
JavaScript 未排序数组中第 k 个最小/最大元素 (预期线性时间)
python
quantdash_cc2 小时前
如何利用标的信息为研究股票池补充名称和交易所信息?
开发语言·python·pandas·量化交易·1024程序员节·股票数据·quantdash
数字化转型分享点滴2 小时前
机加工企业上大数据分析系统有哪些容易踩的坑?
python·1024程序员节
B2_Proxy3 小时前
Scrapy 代理 IP 调度进阶:基于 Redis 与中间件的高可用架构实战
python·scrapy·1024程序员节
在世修行3 小时前
智学文枢:AI 客户端封装
python·http·ai·1024程序员节·pyside
言乐64 小时前
Python实现三轴联动根据数据自动打磨镜片模型
开发语言·python