pin_drop当前位置:知识文库 ❯ 图文

Python Lock互斥锁详解 - 多线程同步与数据安全

概述

互斥锁、acquire/release、with锁。本篇教程将详细介绍线程同步Lock的核心概念和Python中的实际应用。


语法

代码示例

# 线程同步Lock相关语法示例
import threading

# 创建锁
lock = threading.Lock()

# 方式1: acquire/release
lock.acquire()      # 获取锁(阻塞)
lock.acquire(timeout=5)  # 带超时的获取
try:
    # 临界区代码
    pass
finally:
    lock.release()  # 释放锁

# 方式2: with语句(推荐)
with lock:
    # 临界区代码
    pass

# Lock方法
lock.acquire(blocking=True, timeout=-1)  # 获取锁
lock.release()       # 释放锁
lock.locked()        # 检查是否被锁定

基本用法

代码示例

# 基本用法示例
import threading

# 共享资源
counter = 0
lock = threading.Lock()

def increment():
    """线程安全的计数器递增"""
    global counter
    for _ in range(100000):
        with lock:  # 使用with语句自动管理锁
            counter += 1

# 创建多个线程
threads = []
for i in range(5):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

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

print(f"最终计数: {counter}")  # 应该是 500000

代码示例

代码示例

# 详细代码示例:银行账户线程安全操作
import threading
import time
import random

class BankAccount:
    """线程安全的银行账户"""
    def __init__(self, balance=0):
        self.balance = balance
        self.lock = threading.Lock()
    
    def deposit(self, amount):
        """存款"""
        with self.lock:
            old_balance = self.balance
            time.sleep(0.001)  # 模拟操作延迟
            self.balance = old_balance + amount
            print(f"存入 {amount},余额: {self.balance}")
    
    def withdraw(self, amount):
        """取款"""
        with self.lock:
            if self.balance >= amount:
                old_balance = self.balance
                time.sleep(0.001)
                self.balance = old_balance - amount
                print(f"取出 {amount},余额: {self.balance}")
            else:
                print(f"余额不足,当前余额: {self.balance}")

# 创建账户
account = BankAccount(1000)

def deposit_worker(account, times):
    for _ in range(times):
        amount = random.randint(10, 100)
        account.deposit(amount)

def withdraw_worker(account, times):
    for _ in range(times):
        amount = random.randint(10, 50)
        account.withdraw(amount)

# 创建线程
threads = []
for i in range(3):
    t1 = threading.Thread(target=deposit_worker, args=(account, 5))
    t2 = threading.Thread(target=withdraw_worker, args=(account, 5))
    threads.extend([t1, t2])
    t1.start()
    t2.start()

for t in threads:
    t.join()

print(f"最终余额: {account.balance}")
加锁方式 优点 缺点
acquire/release 灵活控制 需要手动释放,易遗漏
with语句 自动释放,代码简洁 灵活性较低

注意事项

注意1:使用线程同步Lock时需要注意的关键点。

注意2:常见的陷阱和最佳实践。


小结

  • 核心概念1:线程同步Lock的核心概念1

  • 核心概念2:线程同步Lock的核心概念2

  • 核心概念3:线程同步Lock的核心概念3


练习题

练习1

编写程序,练习线程同步Lock的基本用法。

练习2

编写一个函数,在实际场景中应用线程同步Lock。

常见问题

什么是互斥锁?为什么需要它?

互斥锁(Mutex Lock)是一种用于多线程同步的机制,确保同一时刻只有一个线程可以访问共享资源。当多个线程同时修改共享数据时,可能导致数据不一致,互斥锁通过加锁/解锁机制保证操作的原子性。

acquire和with语句有什么区别?

acquire/release需要手动管理锁的获取和释放,容易忘记释放导致死锁;with语句自动管理锁的生命周期,进入代码块时自动获取锁,退出时自动释放,即使发生异常也能保证锁被释放,是推荐的使用方式。

什么是死锁?如何避免?

死锁是指两个或多个线程相互等待对方释放锁,导致所有线程都无法继续执行。避免方法包括:1)使用超时机制;2)按固定顺序获取多个锁;3)使用with语句确保锁被释放;4)尽量减少锁的持有时间。

标签: 互斥锁 Lock 线程同步 死锁 Python

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python Thread类详解 - 自定义线程编程指南 下一篇: Python RLock可重入锁详解 - 递归加锁与嵌套调用

poll相关推荐