线程锁

本文深入探讨了线程锁机制在并发编程中的作用,通过具体示例解释了如何使用Python的threading模块来实现资源的排他访问,避免了线程间的资源冲突,确保了数据的一致性和程序的稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

锁机制:类似于事务

一个进程,锁机制完成不了,会变成死锁

做完一件事情前,先锁起来,做完之后再解锁
针对同一个数据,在做是时候希望排他的去做,不希望资源被占用

线程为了避免资源相互征用,所以有一个锁机制,在一件事前先将他所以起来,再做,做完后再释放

锁机制:解决的是一大类问题。资源不允许冲突的去写。
实例化一把锁:

1;锁的一种方式,放入一个list里面

#删除最后一个元素,实际线程的案例,参入了装饰器来记录执行所消耗的时间,
#线程用作万一删除多个,比如3个

import time
import  threading

def runtime(func):
    def warpper(*args,**kwargs):
        starttime=time.time()
        func(*args,**kwargs)
        endtime=time.time()
        print('运行了%d秒'% (endtime-starttime))
    return warpper

lock =threading.Lock()   #锁机制   做事前现锁起来
lista = [1,2,3,4,5,6,7,8,9]

@runtime       #装饰器做的最经典两个事情:1 统计一个事情(这里是记录时间) 2.记录函数运行的日志   附外:3 做权限认证

def pop(listfordel):

    lock.acquire()    #锁定资源     做之前
#因选取的是list3次选择的都是list的最后一个元素,防止资源冲突,用线程锁,防止冲突
    a=listfordel[-1]
    print('即将要删除的元素为%s' % a)
    time.sleep(3)
    listfordel.remove(a)

    lock.release()     #解锁    做完了

if __name__ =='__main__':
    threadlist = []
    for i in range(3):     #模拟删除3个元素
        t=threading.Thread(target=pop,args=(lista,))
        threadlist.append(t)
        print('线程名为%s' % t.getName())     #getName  获取线程的名字
        t.start()

    for i in threadlist:
        i.join()

    print('处理后的lista =%s' % lista)

"""线程名为Thread-1
即将要删除的元素为9
线程名为Thread-2
线程名为Thread-3
即将要删除的元素为8
运行了3秒
即将要删除的元素为7
运行了5秒
运行了8秒
处理后的lista =[1, 2, 3, 4, 5, 6]
"""

import threading
import time
import  os

def dosleep():
    """停顿几秒"""
    time.sleep(1)

def bookticket(tid):
    """模拟订机票"""
    global ticketnumber    #模拟票的数量   相当于全局变量
    global lock         #两行,联系下面的创建锁
    while True:
        lock.acquire()      #得到一个锁,锁定
        if ticketnumber !=0:
            ticketnumber -= 1   #售票,票数减去!
            print('剩下的票为 %s' %{ticketnumber})
            dosleep()
        else:
            print('线程id为 %s,票已经卖完了' % {tid})
            os._exit(0)  #退出程序

        lock.release()
        dosleep()

ticketnumber =10
lock  =threading.Lock()   #创建锁    因为锁是在外面定义的,所以上面的globalyao 要修改

#循环10次
for i in range(10):
    newthread = threading.Thread(target=bookticket,args=( i,))
    newthread.start()
"""
剩下的票为 {9}
剩下的票为 {8}
剩下的票为 {7}
剩下的票为 {6}
剩下的票为 {5}
剩下的票为 {4}
剩下的票为 {3}
剩下的票为 {2}
剩下的票为 {1}
剩下的票为 {0}
线程id为 {0},票已经卖完了
"""
资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 今天给大家分享一个关于C#自定义字符串替换方法的实例,希望能对大家有所帮助。具体介绍如下: 之前我遇到了一个算法题,题目要求将一个字符串中的某些片段替换为指定的新字符串片段。例如,对于源字符串“abcdeabcdfbcdefg”,需要将其中的“cde”替换为“12345”,最终得到的结果字符串是“ab12345abcdfb12345fg”,即从“abcdeabcdfbcdefg”变为“ab12345abcdfb12345fg”。 经过分析,我发现不能直接使用C#自带的string.Replace方法来实现这个功能。于是,我决定自定义一个方法来完成这个任务。这个方法的参数包括:原始字符串originalString、需要被替换的字符串片段strToBeReplaced以及用于替换的新字符串片段newString。 在实现过程中,我首先遍历原始字符串,查找需要被替换的字符串片段strToBeReplaced出现的位置。找到后,就将其替换为新字符串片段newString。需要注意的是,在替换过程中,要确保替换操作不会影响后续的查找和替换,避免遗漏或重复替换的情况发生。 以下是实现代码的大概逻辑: 初始化一个空的字符串result,用于存储最终替换后的结果。 使用IndexOf方法在原始字符串中查找strToBeReplaced的位置。 如果找到了,就将originalString中从开头到strToBeReplaced出现位置之前的部分,以及newString拼接到result中,然后将originalString的查找范围更新为strToBeReplaced之后的部分。 如果没有找到,就直接将剩余的originalString拼接到result中。 重复上述步骤,直到originalStr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值