Python多线程编程:互斥锁与信号量的核心机制解析

顾星河
顾星河
发布时间:2026-10-13 | 4人浏览过
原创

本文深入解析Python多线程编程中的互斥锁(Rlock)与信号量(Semaphore)机制。通过对比分析Rlock的加锁解锁流程、Semaphore的计数逻辑以及BoundedSemaphore的上限检查特性,结合生产者-消费者模型代码示例,阐述如何利用锁机制保护共享数据一致性,避免并发冲突,提升程序安全性与执行效率。

并发编程中的锁机制概述

并发与锁

在多线程环境中,当多个线程共同访问和修改共享数据时,若缺乏有效的保护机制,极易引发数据不一致或竞争条件。为确保数据的一致性与线程安全,通常需要引入锁、信号量或条件变量等同步原语来进行控制。

互斥锁(Rlock)的工作原理与使用规范

互斥锁

互斥锁(Mutex)的核心作用是将关键代码段包裹在锁的保护之下,通过牺牲一定的执行性能来换取数据的安全性。以Python中的Rlock为例,线程在获取锁(acquire)后,必须在执行完毕后显式调用释放锁(release)方法。若忘记释放锁,将导致其他线程无法获取资源,从而丧失多线程并发执行的优势,甚至造成死锁。

互斥锁的基本使用规则如下:

互斥锁代码示例


import threading
# 声明互斥锁
lock=threading.Rlock();
def handle(sid):# 功能实现代码
lock.acquire() #加锁
# writer codeing
lock.relase() #释放锁

信号量(Semaphore)与有界信号量详解

信号量

信号量的操作主要涉及两个核心函数:调用release()会使信号量计数加1,而调用acquire()则使信号量计数减1。

从概念上讲,信号量用于控制对临界资源的访问权限,并作为进入临界区的判断条件,限制同时执行特定代码段的线程数量。

Semaphore类在初始化时不设上限检查,其初始参数通常设为0。调用release()函数时,信号量计数单纯增加1,系统不会检查是否超过预设上限。

BoundedSemaphore(有界信号量)与普通信号量的区别在于,它在调用release()使计数加1的同时,会严格检查信号量是否超过设定的上限值。如果超过上限,将抛出异常,从而防止信号量计数无限增长。

在使用BoundedSemaphore时,不允许将初始值设置为0,否则程序运行时会抛出异常。

因此,BoundedSemaphore的初始值至少应设置为1。在实际应用如生产者-消费者模型中,建议在外部定义一个状态变量,在启动线程前对该变量进行判断,以决定是否需要调用acquire()获取许可,从而更灵活地控制流程。

以下是信号量的基本使用代码示例:

信号量基础用法示例


# 声明信号量:
sema=threading.Semaphore(0); #无上限检查
sema=threading.BuderedSeamphore(1) #有上限检查设置
5
apple=1
def consumner():
seam.acquire(); # ‐1
9
if apple==1:
pass
else: sema2.release();#+ 1
def product():
seam.relarse(); # +1
if apple==1:
pass
else:
print("消费:",apple);

完整的实现代码如下:

生产者-消费者模型完整实现


# -*- coding: utf-8 -*-
"""
Created on Mon Sep 9 21:49:30 2019

@author: DGW-PC
"""
# 信号量解决生产者消费者问题
import random;
import threading;
import time;

# 声明信号量
sema=threading.Semaphore(0);# 必须写参数 0 表示可以使用数
sema2=threading.BoundedSemaphore(1);

apple=1;

def product():#生产者
  global apple;
  apple=random.randint(1,100);
  time.sleep(3);
  print("生成苹果:",apple);
  #sema2.release(); # +1
  if apple==1:
     pass
  else: sema2.release();#+ 1 
    
def consumer():
  print("等待");
  sema2.acquire();# -1
  if apple==1:
    pass
  else:    
    print("消费:",apple);
threads=[];

for i in range(1,3):
  t1=threading.Thread(target=consumer);
  t2=threading.Thread(target=product);
  t1.start();
  t2.start();
  threads.append(t1);
  threads.append(t2);
for x in threads:
  x.join();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表