python 互斥锁,死锁

同步与异步之间的区别:

1.同步:可以理解为线程A和B一块配合工作,A执行到一定程度时要依靠B的某个结
果,于是停下来示意B执行,B执行完将结果给A,然后A继续执行。

2.异步:异步是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态,当有信息返回的时候会通知进程进行处理,这样就可以提高执行的效率了,即异步是我们发出的一个请求,该请求会在后台自动发出并获取数据,然后对数据进行处理,在此过程中,我们可以继续做其他操作,不管它怎么发出请求,不关心它怎么处理数据。

自己理解:
在车间生产零件,可能需要组装一个东西,需要一步步来做,而且按照步骤组装,这是同步,异步在组装同一个东西时候,我们可以用3d打印技术做出来,不用进行一步步组装也能达到成功生产,这可以认为是异步。

python锁
在之前我们了解到python多线程中的全局变量改变问题在线程中改变一个全局变量,多线程开发的时候共享全局变量会带来资源竞争效果。也就是数据不安全。所以为了掌控进程合理对变量的改变,我们用线程锁来控制。

1.互斥锁:个线程几乎同时修改一个共享数据的时候,需要进行同步控制,线程同步能够保证多个
线程安全的访问竞争资源(全局内容),简单的同步机制就是使用互斥锁。
某个线程要更改共享数据时,先将其锁定,此时资源的状态为锁定状态,其他线程就能更
改,直到该线程将资源状态改为非锁定状态,也就是释放资源,其他的线程才能再次锁定资
源。互斥锁保证了每一次只有一个线程进入写入操作。从而保证了多线程下数据的安全性。

自己理解:比如去取钱,当只有一个atm取款机时候,为了金主的安全,取钱时候会给门上锁,金主在取钱过后再打开锁,接着后面的人也一样可以安全的取到钱了。

在这里插入图片描述

from threading import Thread
from threading import Lock
g_num = 0
lock = Lock()
#创建一个全局锁对象
def work1(num):
    global g_num
    lock.acquire() #加锁
    for i in range(num):
        g_num += 1
    lock.release() #解锁
    print('in work1-->',g_num)

def work2(num):
    global g_num
    lock.acquire() #加锁
    for i in range(num):
        g_num += 1
    lock.release() #解锁
    print('in work1-->',g_num)

def main():
    t1 = Thread(target=work1,args=(10000000,)) #100000万次自加一
    t2 = Thread(target=work2,args=(10000000,))
    t1.start()
    t2.start()
    t2.join()

if __name__ == '__main__':
    main()
    print('main :', g_num)

#结果:
in work1--> 10000000
in work1--> 20000000
main : 20000000

2.死锁:在多个线程共享资源的时候,如果两个线程分别占有一部分资源,并且同时等待对方的资
源,就会造成死锁现象。如果锁之间相互嵌套,就有可能出现死锁。因此尽量不要出现锁之间的嵌套

from threading import Thread
from threading import Lock
lock1 = Lock()
lock2 = Lock()
import time
def work1(num):
    lock1.acquire() #1上锁
    print('work1,上锁1')
    time.sleep(1)
    lock2.acquire() #2上锁
    print('work1,上锁2')
    lock2.release() #1解锁
    print('解锁2')
    lock1.release() #2解锁
    print('解锁1')

def work2(num):
    lock2.acquire()
    print('work2,上锁1')
    lock1.acquire()
    print('work2,上锁2')
    lock1.release()
    print('解锁1')
    lock2.release()
    print('解锁2')

if __name__ == '__main__':
    t1 = Thread(target=work1,args=(1000000,))
    t2 = Thread(target=work2,args=(1000000,))
    t1.start()
    t2.start()

运行:
在这里插入图片描述
给两个线程都安了两把锁,在work1锁完后使用资源,等待1秒,同时work2也上了锁,使用资源,这时候出现都在用一部分资源,都在等待对方的资源,所以形成一个僵局,变成死锁了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python 中,可以使用互斥锁(mutex)来实现多线程的互斥操作。互斥锁是一种同步原语,它能确保在同一时刻只有一个线程可以进入被保护的临界区。 下面是一个简单的示例,演示了如何使用互斥锁来保护共享资源: ```python import threading # 创建一个互斥锁对象 mutex = threading.Lock() # 共享资源 shared_resource = 0 def increment(): global shared_resource for _ in range(1000000): # 使用互斥锁来保护共享资源 mutex.acquire() shared_resource += 1 mutex.release() def decrement(): global shared_resource for _ in range(1000000): # 使用互斥锁来保护共享资源 mutex.acquire() shared_resource -= 1 mutex.release() # 创建两个线程 t1 = threading.Thread(target=increment) t2 = threading.Thread(target=decrement) # 启动线程 t1.start() t2.start() # 等待线程结束 t1.join() t2.join() print("Shared resource value:", shared_resource) ``` 在上面的示例中,我们使用了 `threading.Lock()` 创建了一个互斥锁对象 `mutex`。在 `increment()` 和 `decrement()` 函数中,我们使用 `mutex.acquire()` 来获取锁,并使用 `mutex.release()` 来释放锁。这样可以确保在任意时刻只有一个线程可以访问共享资源 `shared_resource`。 请注意,互斥锁是一种比较低级的同步原语,如果使用不当可能会导致死锁等问题。因此,在编写多线程代码时,需要仔细考虑锁的使用方式,以避免潜在的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值