zoukankan      html  css  js  c++  java
  • Python并发编程—同步互斥

    同步互斥

    线程间通信方法

    1.通信方法:线程间使用全局变量进行通信

    2.共享资源争夺

    • 共享资源:多个进程或者线程都可以操作的资源称为共享资源。对共享资源的操作代码段称为临界区。
    • 影响 : 对共享资源的无序操作可能会带来数据的混乱,或者操作错误。此时往往需要同步互斥机制协调操作顺序。

    3.同步互斥机制

    同步 : 同步是一种协作关系,为完成操作,多进程或者线程间形成一种协调,按照必要的步骤有序执行操作。

    互斥 : 互斥是一种制约关系,当一个进程或者线程占有资源时会进行加锁处理,此时其他进程线程就无法操作该资源,直到解锁后才能操作。

    线程同步互斥方法

    线程Event

    from threading import Event

    e = Event() 创建线程event对象

    e.wait([timeout]) 阻塞等待e被set

    e.set() 设置e,使wait结束阻塞

    e.clear() 使e回到未被设置状态

    e.is_set() 查看当前e是否被设置

     1 from threading import Thread,Event
     2 
     3 s = None  # 用于通信
     4 e = Event() # 创建event对象
     5 
     6 def 杨子荣():
     7   print("杨子荣前来拜山头")
     8   global s
     9   s = "天王盖地虎"
    10   e.set()  # 对e设置
    11 
    12 t = Thread(target=杨子荣)
    13 t.start()
    14 
    15 print("说对口令就是自己人")
    16 e.wait()  # 阻塞等待口令说出
    17 if s == '天王盖地虎':
    18   print("宝塔镇河妖")
    19   print("确认过眼神,你是对的人")
    20 else:
    21   print("打死他...")
    22 
    23 t.join()
    24 
    25 # 说对口令就是自己人
    26 # 杨子荣前来拜山头
    27 # 宝塔镇河妖
    28 # 确认过眼神,你是对的人
    同步互斥方法演示

    线程锁 Lock

    from threading import Lock

    lock = Lock() 创建锁对象

    lock.acquire() 上锁 如果lock已经上锁再调用会阻塞

    lock.release() 解锁

    with lock: 上锁

    ...

    ...

    with代码块结束自动解锁

     1 from threading import Thread,Lock
     2 
     3 a = b = 0
     4 lock = Lock() # 定义锁
     5 
     6 def value():
     7   while True:
     8     lock.acquire()  # 上锁
     9     if a != b:
    10       print("a = %d,b = %d"%(a,b))
    11     lock.release() # 解锁
    12 
    13 t = Thread(target = value)
    14 t.start()
    15 
    16 while True:
    17   with lock:
    18     a += 1
    19     b += 1
    20 
    21 t.join()
    线程lock锁演示

    死锁及其处理

    1.定义:死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。

    2.死锁产生条件

    • 死锁发生的必要条件
    • 互斥条件:指线程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
    • 请求和保持条件:指线程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求线程阻塞,但又对自己已获得的其它资源保持不放。
    • 不剥夺条件:指线程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放,通常CPU内存资源是可以被系统强行调配剥夺的。
    • 环路等待条件:指在发生死锁时,必然存在一个线程——资源的环形链,即进程集合{T0,T1,T2,···,Tn}中的T0正在等待一个T1占用的资源;T1正在等待T2占用的资源,……,Tn正在等待已被T0占用的资源。

    3.死锁的产生原因

    简单来说造成死锁的原因可以概括成三句话:

    • 当前线程拥有其他线程需要的资源
    • 当前线程等待其他线程已拥有的资源
    • 都不放弃自己拥有的资源

    4.如何避免死锁

    死锁是我们非常不愿意看到的一种现象,我们要尽可能避免死锁的情况发生。通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率。

     1 import time
     2 import threading
     3 
     4 # 交易类
     5 class Account:
     6   def __init__(self,_id,balance,lock):
     7     self.id = _id # 用户
     8     self.balance = balance # 存款
     9     self.lock = lock #
    10 
    11   # 取钱
    12   def withdraw(self,amount):
    13     self.balance -= amount
    14 
    15   # 存钱
    16   def deposit(self,amount):
    17     self.balance += amount
    18 
    19   # 查看余额
    20   def get_balance(self):
    21     return self.balance
    22 
    23 # 创建账户
    24 Tom = Account('Tom',5000,threading.Lock())
    25 Alex = Account('Alex',8000,threading.Lock())
    26 
    27 # 转账函数
    28 def  transfer(from_,to,amount):
    29   if from_.lock.acquire():  #锁自己账户
    30     from_.withdraw(amount) # 自己账户减少
    31     time.sleep(0.5)
    32     if to.lock.acquire(): # 对方账户上锁
    33       to.deposit(amount)
    34       to.lock.release()  # 对方账户解锁
    35     from_.lock.release() # 自己账户解锁
    36   print("%s 给 %s转账完成"%(from_.id,to.id))
    37 
    38 t1 = threading.Thread(target = transfer,
    39                        args=(Tom,Alex,2000))
    40 t2 = threading.Thread(target = transfer,
    41                        args=(Alex,Tom,2000))
    42 t1.start()
    43 t2.start()
    44 t1.join()
    45 t2.join()
    线程死锁演示
  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/maplethefox/p/10989243.html
Copyright © 2011-2022 走看看