首页 > 其他分享 >互斥锁

互斥锁

时间:2024-01-17 20:46:03浏览次数:14  
标签:tickets 余票 name 用户 dic 互斥

【一】互斥锁

  • 互斥锁(Mutex,全称 Mutual Exclusion Lock)是一种用于控制多个线程对共享资源访问的同步机制。它的核心概念是确保同一时间只有一个线程可以访问某个特定的资源或代码块。互斥锁可以避免资源的并发访问造成的数据冲突和不一致的问题。

  • 使用互斥锁时,通常遵循以下步骤:

  1. 锁定(Locking):当线程需要访问共享资源时,它首先尝试锁定互斥锁。
  2. 使用资源:如果互斥锁未被其他线程占用,该线程锁定互斥锁并访问资源。
  3. 解锁(Unlocking):访问完成后,线程释放(解锁)互斥锁,使得其他线程可以访问该资源。
  • 以12306买票的例子来说明互斥锁的作用: 假设有一个火车只剩下2张票,现在有多个人(进程)同时在12306上尝试购买这张票。

【二】没有互斥锁的情况

  • 如果没有互斥锁,可能会出现多个人同时看到票还在,于是他们都尝试购买。这可能导致超卖的情况,即系统错误地认为有多张票被卖出。
# 模拟抢票过程

from multiprocessing import Process
import time
import json
import random


# 查票
def search_ticket(name):
    # 读取文件,查询车票数量
    with open('data/tickets', 'r', encoding='utf-8') as fp:
        dic = json.load(fp)
        tickets_num = dic.get("tickets_num")
        print(f'用户{name}查询余票:>>>>{tickets_num}')
    return tickets_num, dic


def save_data(dic):
    with open('data/tickets', 'w', encoding='utf-8') as fp:
        json.dump(dic, fp, ensure_ascii=False)


def buy_tickets(name):
    tickets_num, dic = search_ticket(name=name)
    time.sleep(random.randint(1, 3))  # 模拟随机延迟
    if tickets_num > 0:
        tickets_num -= 1
        dic["tickets_num"] = tickets_num
        save_data(dic=dic)
        print(f'用户{name}买票成功')
    else:
        print(f'用户{name}买票失败')


def process(name):
    search_ticket(name=name)
    buy_tickets(name=name)


if __name__ == '__main__':
    for i in range(5):
        p = Process(target=process, args=(i,))
        p.start()
'''
用户0查询余票:>>>>2
用户1查询余票:>>>>2
用户0查询余票:>>>>2
用户1查询余票:>>>>2
用户2查询余票:>>>>2
用户2查询余票:>>>>2
用户3查询余票:>>>>2
用户3查询余票:>>>>2
用户4查询余票:>>>>2
用户4查询余票:>>>>2
用户0买票成功
用户1买票成功
用户4买票成功
用户2买票成功
用户3买票成功
进程已结束,退出代码0

'''

【三】有互斥锁的情况

  • 使用互斥锁后,当一个人尝试购买这张票时,系统会锁定这个操作。这时,其他人虽然也在尝试购买,但由于互斥锁已经被占用,他们无法同时进行购票操作。只有当第一个人完成购买(无论成功与否)并释放了互斥锁,其他人才能继续尝试购买。这就确保了不会发生超卖的情况。
# 有互斥锁的情况

# 模拟抢票过程

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


# 查票
def search_ticket(name):
    # 读取文件,查询车票数量
    with open('data/tickets', 'r', encoding='utf-8') as fp:
        dic = json.load(fp)
        tickets_num = dic.get("tickets_num")
        print(f'用户{name}查询余票:>>>>{tickets_num}')
    return tickets_num, dic


def save_data(dic):
    with open('data/tickets', 'w', encoding='utf-8') as fp:
        json.dump(dic, fp, ensure_ascii=False)


def buy_tickets(name):
    tickets_num, dic = search_ticket(name=name)
    time.sleep(random.randint(1, 3))  # 模拟随机延迟
    if tickets_num > 0:
        tickets_num -= 1
        dic["tickets_num"] = tickets_num
        save_data(dic=dic)
        print(f'用户{name}买票成功')
    else:
        print(f'用户{name}买票失败')


def process(name, mutex):
    search_ticket(name=name)
    # 抢锁
    mutex.acquire()
    buy_tickets(name=name)
    # 释放锁
    mutex.release()


if __name__ == '__main__':
    mutex = Lock()
    for i in range(5):
        p = Process(target=process, args=(i, mutex))
        p.start()
'''
用户1查询余票:>>>>2
用户1查询余票:>>>>2
用户0查询余票:>>>>2
用户2查询余票:>>>>2
用户3查询余票:>>>>2
用户4查询余票:>>>>2
用户1买票成功
用户0查询余票:>>>>1
用户0买票成功
用户2查询余票:>>>>0
用户2买票失败
用户3查询余票:>>>>0
用户3买票失败
用户4查询余票:>>>>0
用户4买票失败

进程已结束,退出代码0


'''

【四】注意

  • 不要轻易加锁,加锁只应该在争夺数据的环节加

标签:tickets,余票,name,用户,dic,互斥
From: https://www.cnblogs.com/Hqqqq/p/17971132

相关文章

  • 进程锁(互斥锁)
    进程锁(互斥锁)(1)简介进程锁(也称为互斥锁)是一种用于控制多个进程对共享资源访问的机制。在并发编程中,多个进程可能同时访问共享的数据,如果没有适当的同步机制,可能会导致数据不一致或其他问题。进程锁就是用来解决这个问题的一种同步工具。互斥锁的基本思想是,在访问共享资源......
  • 条件变量pthread_cond_wait()和pthread_cond_signal()——需要和互斥锁一起使用——转
    条件变量pthread_cond_wait()和pthread_cond_signal()详解转载——原博客地址:https://www.cnblogs.com/cthon/p/9084735.html 条件变量     条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线......
  • MFC---多线程(基本概念和线程同步之互斥对象)
    基本概念引入一个题目:Bingo老师提了一个需求:打印每隔3秒叫martin老师做一次俯卧撑持续20次每隔1秒钟叫rock老师甩头发持续50次每隔2秒钟叫西西老师唱歌持续40次线程(CPU调度和分派的基本单位)线程是在进程中产生的一个执行单元,是CPU调度和分配的最小单元,其在同一个进程中与......
  • 智能指针和互斥锁
    RAII:ResourceAcquisitionIsInitialization(资源获取即初始化)classDynamicArray{private:int*data;//指向动态分配的数组的指针public:DynamicArray(intsize){data=newint[size];//在构造函数中分配内存}~DynamicArray(){......
  • 多线程(互斥锁,条件变量,虚假唤醒)知识点总结
    互斥锁mutexC++11一共提出四种互斥锁std::mutex:独占的互斥锁,不能递归使用std::timed_mutex:带超时的独占互斥锁,不能递归使用std::recursive_mutex:递归互斥锁,不带超时功能std::recursive_timed_mutex:带超时的递归互斥锁1.mutexmutex有三个成员函数:voidlock();booltry_loc......
  • FreeRTOS中的中断中能否使用互斥量
    在嵌入式系统中,实时操作系统(RTOS)是为了确保任务的实时性和协同工作而设计的。FreeRTOS作为一款流行的RTOS,提供了丰富的同步和通信机制,其中互斥量是一种用于保护共享资源的关键工具。然而,开发者在使用FreeRTOS时,经常会面临一个问题,即在中断中是否可以安全地使用互斥量。本文将深入讨......
  • [C++] 互斥锁(unique_lock、lock_guard)
    作者:丶布布......
  • 4.进程同步与互斥
    生产者消费者问题一组生产者进程和一组消费者进程共享一个初始为空,大小为n的缓冲区。当缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待,只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。......
  • FreeRTOS中信号量和互斥量背后的原理
    FreeRTOS是一个流行的嵌入式实时操作系统,提供了信号量和互斥量等同步机制来协调任务之间的访问共享资源。本文将深入探讨FreeRTOS中信号量和互斥量的背后原理,以及如何使用这些机制确保系统的稳定性和性能。1.信号量和互斥量的概念1.1信号量信号量是一种计数器,用于控制多个任务对......
  • FreeRTOS--互斥量
    示例源码基于FreeRTOSV9.0.0互斥量1.概述互斥量用于临界资源的保护,通过互斥量,多个任务对相同资源进行的访问操作是互斥的;互斥量的核心在于谁上锁,就由谁解锁,这只是约定,FreeRTOS并没有在代码上实现这一点;互斥量是一种特殊的信号量,也是一种特殊的队列;使用互斥量,需要开启宏con......