代码之家  ›  专栏  ›  技术社区  ›  Jasiu

这种Python生产者-消费者无锁方法是线程安全的吗?

  •  6
  • Jasiu  · 技术社区  · 17 年前

    QUEUE_ITEM = None
    
    # this is executed in one threading.Thread object
    def producer():
        global QUEUE_ITEM
        while True:
            i = produce_item()
            QUEUE_ITEM = i
    
    # this is executed in another threading.Thread object
    def consumer():
        global QUEUE_ITEM
        while True:
            i = QUEUE_ITEM
            consume_item(i)
    

    我的问题是:这段代码是线程安全的吗?

    del x __del__ 方法。因此,如果我的物品有

    6 回复  |  直到 17 年前
        1
  •  6
  •   Dustin    17 年前

        2
  •  2
  •   Unknown    17 年前

    方法。因此,如果我的物品有

    不过,不用费心使用这个。你最终会在毫无意义的轮询周期中耗尽CPU,而且它并不比使用带锁的队列快,因为Python已经有了全局锁。

        3
  •  1
  •   David Locke    17 年前

    真的 QUEUE_ITEM 在消费者消费之前,消费者可以消费 队列项 两次。正如你提到的,你对此没问题,但大多数人都不这么认为。

        4
  •  0
  •   Bastien Léonard    17 年前

        5
  •  0
  •   null    17 年前

    QUEUE = []
    
    # this is executed in one threading.Thread object
    def producer():
        global QUEUE
        while True:
            i = produce_item()
            QUEUE.append(i)
    
    # this is executed in another threading.Thread object
    def consumer():
        global QUEUE
        while True:
            try:
                i = QUEUE.pop(0)
            except IndexError:
                # queue is empty
                continue
    
            consume_item(i)
    

    在下面这样的类作用域中,您甚至可以清除队列。

    class Atomic(object):
        def __init__(self):
            self.queue = []
    
        # this is executed in one threading.Thread object
        def producer(self):
            while True:
                i = produce_item()
                self.queue.append(i)
    
        # this is executed in another threading.Thread object
        def consumer(self):
            while True:
                try:
                    i = self.queue.pop(0)
                except IndexError:
                    # queue is empty
                    continue
    
                consume_item(i)
    
        # There's the possibility producer is still working on it's current item.
        def clear_queue(self):
            self.queue = []
    

        6
  •  0
  •   Paweł Polewicz    17 年前

    __del__ QUEUE_ITEM

    increase the reference counter on the old object
    assign a new one to `QUEUE_ITEM`
    decrease the reference counter on the old object