代码之家  ›  专栏  ›  技术社区  ›  Subhayan Bhattacharya

使用线程python中的条件并发访问共享资源

  •  0
  • Subhayan Bhattacharya  · 技术社区  · 6 年前

    我有下面的示例基本代码,用于在Python中处理条件:

    import threading
    import random
    import time
    
    class Producer(threading.Thread):
        """
        Produces random integers to a list
        """
    
        def __init__(self, integers, condition):
            """
            Constructor.
    
            @param integers list of integers
            @param condition condition synchronization object
            """
            threading.Thread.__init__(self)
            self.integers = integers
            self.condition = condition
    
        def run(self):
            """
            Thread run method. Append random integers to the integers list
            at random time.
            """
            while True:
                integer = random.randint(0, 256)
                self.condition.acquire()
                print 'condition acquired by %s' % self.name
                self.integers.append(integer) 
                print '%d appended to list by %s' % (integer, self.name)
                print 'condition notified by %s' % self.name
                self.condition.notify()
                print 'condition released by %s' % self.name
                self.condition.release()
                time.sleep(1)
    
    class Consumer(threading.Thread):
        """
        Consumes random integers from a list
        """
    
        def __init__(self, integers, condition):
            """
            Constructor.
    
            @param integers list of integers
            @param condition condition synchronization object
            """
            threading.Thread.__init__(self)
            self.integers = integers
            self.condition = condition
    
        def run(self):
            """
            Thread run method. Consumes integers from list
            """
            while True:
                self.condition.acquire()
                print 'condition acquired by %s' % self.name
                while True:
                    if self.integers:
                        integer = self.integers.pop()
                        print '%d popped from list by %s' % (integer, self.name)
                        break
                    print 'condition wait by %s' % self.name
                    self.condition.wait()
                print 'condition released by %s' % self.name
                self.condition.release()
    
    def main():
        integers = []
        condition = threading.Condition()
        t1 = Producer(integers, condition)
        t2 = Consumer(integers, condition)
        t1.start()
        t2.start()
        t1.join()
        t2.join()
    
    if __name__ == '__main__':
        main()
    

    根据我的理解,当消费者致电 wait() 方法缓解病情进入睡眠状态。

    当生产者在调用后通知线程时 notify() 似乎两个消费者都没有在试图从整数列表中弹出之前重新获取条件。

    这不是比赛条件吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   shmee    6 年前

    消费者从睡梦中醒来后,无需重新了解情况。 wait() 因为他们在恢复之前不会释放它 WAIT() .
    它们释放的是一个始终与条件关联的锁,无论是显式的还是隐式的。
    docs :

    条件变量总是与某种锁相关联;可以传入该锁,或者默认情况下将创建一个锁。 […] 锁是Condition对象的一部分:您不必单独跟踪它。

    通过获取/释放条件以及调用时隐式获取和释放锁 wait() RESP从中醒来。

    Acquire()和Release()方法还调用关联锁的相应方法。
    […]
    wait()方法释放锁,然后阻塞,直到另一个线程通过调用notify()或notify_all()将其唤醒。一旦唤醒,wait()将重新获取锁并返回。

    因此,始终有最多一个线程可以持有锁,从而在任何给定时间点安全地修改共享资源。