python中线程同步机制 lock

在Python中,线程同步可以通过threading.Lock对象来实现。下面是一个使用threading.Lock来确保多线程访问共享资源互斥的示例:

import threading
import time

# 共享资源
shared_resource = 0

# 创建一个Lock对象
lock = threading.Lock()

def worker_thread(id):
    global shared_resource
    
    # 在修改共享资源之前获取锁
    lock.acquire()
    
    try:
        print(f"线程 {id} 开始访问共享资源")
        
        # 模拟耗时操作,如IO或计算
        time.sleep(1)
        
        # 修改共享资源
        shared_resource += 1
        
        print(f"线程 {id} 结束访问并更新了共享资源,当前值为:{shared_resource}")
    finally:
        # 访问结束后释放锁,允许其他线程获取
        lock.release()

# 创建两个线程
threads = []
for i in range(2):
    thread = threading.Thread(target=worker_thread, args=(i,))
    threads.append(thread)
    thread.start()

# 等待所有线程完成
for thread in threads:
    thread.join()

print("所有线程已完成,最终共享资源的值应为2")

在这个例子中,threading.Lock()创建了一个锁对象。当多个线程尝试访问共享资源(这里是变量shared_resource)时,每个线程都会先调用lock.acquire()来获取锁。如果锁已被另一个线程持有,则该线程会阻塞,直到锁被释放。在try/finally块中确保无论发生什么情况,最后都会通过lock.release()释放锁,以保证其他线程能够继续访问共享资源。

  • 下面我们实现一个简单的生产者-消费者模式,使用threading.Lock实现生产者-消费者模式时,可以确保同一时间只有一个线程(生产者或消费者)访问共享资源(例如,一个队列)。下面是一个简单的示例,其中生产者将数字放入队列,并且消费者从队列中取出并打印数字。这里我们用列表作为简单的队列,并使用锁和条件变量来同步生产与消费:
import threading
import random
import time

# 共享资源:队列和锁
queue = []
max_queue_size = 10
lock = threading.Lock()
not_full = threading.Condition(lock)  # 当队列未满时通知生产者
not_empty = threading.Condition(lock)  # 当队列非空时通知消费者

def producer(id, total_items):
    global queue
    for _ in range(total_items):
        not_full.acquire()  # 获取锁并等待队列不满
        while len(queue) == max_queue_size:
            print(f"生产者{id}:队列已满,等待消费者消耗...")
            not_full.wait()
        
        item = random.randint(1, 100)
        queue.append(item)
        print(f"生产者{id} 生产了商品 {item},当前队列长度: {len(queue)}")
        
        not_empty.notify()  # 通知消费者队列中有新的元素
        not_full.release()  # 释放锁

def consumer(id):
    global queue
    while True:
        not_empty.acquire()  # 获取锁并等待队列不为空
        while not queue:
            print(f"消费者{id}:队列为空,等待生产者生产...")
            not_empty.wait()

        item = queue.pop(0)
        print(f"消费者{id} 消费了商品 {item},当前队列长度: {len(queue)}")

        not_full.notify()  # 告知生产者队列有空间可放新元素
        not_empty.release()  # 释放锁

# 创建并启动生产者和消费者线程
producer_threads = [threading.Thread(target=producer, args=(i, 5)) for i in range(2)]
consumer_thread = threading.Thread(target=consumer, args=(1,))

for thread in producer_threads:
    thread.start()

consumer_thread.start()

# 等待所有线程完成
for thread in producer_threads:
    thread.join()

consumer_thread.join()

print("所有生产者和消费者已完成任务")

在这个例子中,生产者通过not_full条件变量等待队列不满,然后添加产品到队列,并唤醒等待的消费者。消费者则通过not_empty条件变量等待队列非空,然后从队列中取出并消费产品,并唤醒等待的生产者。通过这种方式,生产者和消费者之间实现了有效的同步,避免了并发访问队列时的数据竞争问题。

  • 35
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

semicolon_helloword

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值