首页 > 系统相关 >进程锁(互斥锁)

进程锁(互斥锁)

时间:2024-01-17 16:55:41浏览次数:27  
标签:__ name 互斥 dict 进程 ticket

进程锁(互斥锁)

(1)简介

  • 进程锁(也称为互斥锁)是一种用于控制多个进程对共享资源访问的机制。在并发编程中,多个进程可能同时访问共享的数据,如果没有适当的同步机制,可能会导致数据不一致或其他问题。进程锁就是用来解决这个问题的一种同步工具。

  • 互斥锁的基本思想是,在访问共享资源之前,进程首先必须获得锁。如果锁已经被其他进程获得,那么进程就必须等待,直到锁被释放。这样可以确保同一时刻只有一个进程可以访问共享资源,从而避免了竞态条件和数据不一致的问题。

(2)多个进程共享同一文件

  • 文件当数据库,模拟抢票
  • 并发运行,数据写入错乱

(1)未加锁示例

import random
from multiprocessing import Process, Lock
import time
import json
import os

# 确定存储车票信息的文件路径
db_path = os.path.join(os.path.dirname(__file__), 'ticket_data.json')


# 初始化车票数据
def init_data():
    with open(file=db_path, mode='w', encoding='utf-8') as fp:
        json.dump({'ticket_number': 2}, fp)


# 获取车票数据
def get_ticket():
    with open(db_path, 'r', encoding='utf8') as f:
        ticket_dict = json.load(f)
    return ticket_dict


# 保存车票数据
def save_ticket(ticket_dict):
    with open(db_path, 'w', encoding='utf8') as f:
        json.dump(ticket_dict, f)


# 查询车票
def search_ticket(name):
    ticket_dict = get_ticket()
    print(f'用户:>>>{name} 正在查询余票:>>>{ticket_dict.get("ticket_number")}')


# 购买车票
def buy_ticket(name):
    ticket_dict = get_ticket()

    # 模拟购票过程中的随机延迟
    time.sleep(random.randint(1, 3))

    if ticket_dict.get('ticket_number') > 0:
        ticket_dict['ticket_number'] -= 1
        save_ticket(ticket_dict)
        print(f'用户:>>>{name} 买票成功!!')
    else:
        print(f'当前无余票!!')


# 主函数,包括查询和购买操作
def main(name):
    search_ticket(name)
    buy_ticket(name)


if __name__ == '__main__':
    # 初始化车票数据
    init_data()

    # 创建进程列表
    p_list = []

    # 创建多个进程模拟多用户同时操作
    for i in range(1, 5):
        p = Process(target=main, args=(i,))
        p.start()
        p_list.append(p)

    # 等待所有进程执行完毕
    for p in p_list:
        p.join()

# 用户:>>>1 正在查询余票:>>>2
# 用户:>>>4 正在查询余票:>>>2
# 用户:>>>2 正在查询余票:>>>2
# 用户:>>>3 正在查询余票:>>>2
# 用户:>>>1 买票成功!!
# 用户:>>>4 买票成功!!
# 用户:>>>3 买票成功!!
# 用户:>>>2 买票成功!!

(2)加锁

  • 针对上述数据错乱问题,解决方式就是加锁处理
    • 将并发变成串行牺牲效率,但是保证了数据的安全
import random
from multiprocessing import Process, Lock
import time
import json
import os

# 确定存储车票信息的文件路径
db_path = os.path.join(os.path.dirname(__file__), 'ticket_data.json')


# 初始化车票数据
def init_data():
    with open(file=db_path, mode='w', encoding='utf-8') as fp:
        json.dump({'ticket_number': 2}, fp)


# 获取车票数据
def get_ticket():
    with open(db_path, 'r', encoding='utf8') as f:
        ticket_dict = json.load(f)
    return ticket_dict


# 保存车票数据
def save_ticket(ticket_dict):
    with open(db_path, 'w', encoding='utf8') as f:
        json.dump(ticket_dict, f)


# 查询车票
def search_ticket(name):
    ticket_dict = get_ticket()
    print(f'用户:>>>{name} 正在查询余票:>>>{ticket_dict.get("ticket_number")}')


# 购买车票
def buy_ticket(name, mutex):
    ticket_dict = get_ticket()

    time.sleep(random.randint(1, 3))

    if ticket_dict.get('ticket_number') > 0:
        ticket_dict['ticket_number'] -= 1
        save_ticket(ticket_dict)
        print(f'用户:>>>{name} 买票成功!!')
    else:
        print(f'当前无余票!!')


# 主函数,包括查询和购买操作
def main(name, mutex):
    search_ticket(name)

    # 请求互斥锁
    mutex.acquire()

    try:
        buy_ticket(name, mutex)
    finally:
        # 释放互斥锁
        mutex.release()


if __name__ == '__main__':
    # 初始化车票数据
    init_data()

    # 创建互斥锁
    mutex = Lock()

    # 创建进程列表
    p_list = []

    # 创建多个进程模拟多用户同时购票操作
    for i in range(1, 5):
        p = Process(target=main, args=(i, mutex))
        p.start()
        p_list.append(p)

    # 等待所有进程执行完毕
    for p in p_list:
        p.join()

    # 所有人都能查票成功,但是只有前两名购票成功
    # 前两名是随机抢到的,不一定是按顺序(考虑到各种因素,如网络等)
    # 用户:>>>1 正在查询余票:>>>2
    # 用户:>>>4 正在查询余票:>>>2
    # 用户:>>>3 正在查询余票:>>>2
    # 用户:>>>2 正在查询余票:>>>2
    # 用户:>>>1 买票成功!!
    # 用户:>>>4 买票成功!!
    # 当前无余票!!
    # 当前无余票!!
  • mutex = Lock(): 创建了一个互斥锁对象。
  • mutex.acquire(): 请求互斥锁,如果锁已经被其他进程占用,会阻塞等待。
  • try 中的代码块:在互斥锁保护下执行购票操作。
  • finally 中的代码块:无论购票操作是否成功,都会释放互斥锁,确保其他进程可以访问共享资源。
  • 进程列表 p_list:存储了所有创建的进程对象,用于后续等待所有进程执行完毕。

标签:__,name,互斥,dict,进程,ticket
From: https://www.cnblogs.com/ssrheart/p/17970415

相关文章

  • 条件变量pthread_cond_wait()和pthread_cond_signal()——需要和互斥锁一起使用——转
    条件变量pthread_cond_wait()和pthread_cond_signal()详解转载——原博客地址:https://www.cnblogs.com/cthon/p/9084735.html 条件变量     条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线......
  • 查看Buffer&Cache被哪些进程占用
    背景介绍根据运营反馈线上环境监控图表ResponseTime出现了波动,由于我之前处理过类似的情况,上次是由于Redis占用大量内存没有释放的问题导致的,所以这次我也从内存着手进行分析问题的原因。(虽然最后确定导致此问题的原因是Java代码中的问题,但对于cache内容被那些进程所占用的,仍然......
  • python3之多进程线程
    本文内容参考https://www.liaoxuefeng.com/wiki/1016959663602400/1017628290184064 多进程os模块的fork()多进程(multiprocessing):Unix/Linux操作系统提供了一个fork()函数,fork()函数调用时,操作系统自动把当前进程(父进程)复制了一份(子进程),然后分别在父进程和子进程内返回。......
  • 进程
    进程在Python中,进程(Process)是计算机中正在执行的程序的独立实例。每个进程都有自己的内存空间、变量、文件描述符等资源,是操作系统进行任务调度和资源管理的基本单位。Python提供了multiprocessing模块,使得在Python中创建和管理进程变得相对容易。以下是一些关于Python......
  • 对进程以及创建进程的理解
    【一】进程和程序【1】什么是进程?进程就是正在运行的程序【2】谁来执行进程?cpu【3】进程和程序的区别?程序是存储再硬盘里面的一堆代码和数据进程是正在运行的程序【二】进程调度问题有一个算法叫做任务调度算法就像是一个非常聪明的调度员,在计算机系统中负责安排......
  • MFC---多线程(基本概念和线程同步之互斥对象)
    基本概念引入一个题目:Bingo老师提了一个需求:打印每隔3秒叫martin老师做一次俯卧撑持续20次每隔1秒钟叫rock老师甩头发持续50次每隔2秒钟叫西西老师唱歌持续40次线程(CPU调度和分派的基本单位)线程是在进程中产生的一个执行单元,是CPU调度和分配的最小单元,其在同一个进程中与......
  • 内存取证1-进程
    otterctf内存取证-----4-NameGame看到这题目,看看是不是浏览器登录,无果。这里似乎没有跟题干相关的答案。游戏登录了,登录进程里是不是包含账户信息,把进程dump下来看看。频道后面是不是账户名字,果然猜对了,上面都是假想自己做出来的,感觉蛮有意思的,所以记录下来,进程里居然......
  • 车机必备软件-小白点EasyTouch(类似苹果的悬浮球,返回,清理垃圾,杀进程)
    简介有些小伙伴升级车机后,由于部分软件打开后处于全屏状态无法返回,这里我教大家如何解决。解决办法就是:在车机上安装这款小白点软件,这款软件体积小巧,不占内存,操作也十分方便,它能帮助你快速回到主屏幕和返回上一个界面。界面展示caplay界面普通车机界面软件功能1、主屏......
  • 智能指针和互斥锁
    RAII:ResourceAcquisitionIsInitialization(资源获取即初始化)classDynamicArray{private:int*data;//指向动态分配的数组的指针public:DynamicArray(intsize){data=newint[size];//在构造函数中分配内存}~DynamicArray(){......
  • Linux进程管理
    一、什么是进程进程是加载到内存中的一段指令。如果某个用户运行一个程序,那么这个程序产生的进程也会继承到这个用户的UID和GID以及SELINUX的上下文,并且进程还具有父子关系,一个父进程可以有多个子进程二、查看进程2.1ps查看进程信息用法作用ps查看当前终端的进程ps-a查看所有终......