为什么信号量的值没有全局变化

2024-05-20 23:19:13 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我目前的代码,主要问题是我使用Semphore来控制两个进程的输出,但是似乎Semphore没有全局改变,即当进程“producer”将Semphore更改为2时,进程“consumer”仍然认为Semphore为零,这导致它永远等待。你知道吗

from multiprocessing import Process, Semaphore, Queue
import time
from random import random

buffer = Queue(10)
empty = Semaphore(2)
full = Semaphore(0)

class Consumer(Process):

    def run(self):
        global buffer, empty, full
        while True:
            time.sleep(4)
            print(full)
            full.acquire()
            buffer.get()
            print('Consumer get')
            time.sleep(1)
            empty.release()


class Producer(Process):

    def run(self):
        global buffer, empty, full
        while True:
            empty.acquire()
            print ('Producer put ')
            time.sleep(1)
            full.release()
            buffer.put(1)
            print(full)


if __name__ == '__main__':
    p = Producer()
    c = Consumer()
    p.daemon = c.daemon = True
    p.start()
    c.start()
    p.join()
    c.join()
    print ('Ended!')

输出为

Producer put
<Semaphore(value=1)>
Producer put
<Semaphore(value=2)>
<Semaphore(value=0)>

我不知道该怎么做才能让“消费者”过程检测到变化。你知道吗


Tags: producerimporttruetimeput进程consumerbuffer
1条回答
网友
1楼 · 发布于 2024-05-20 23:19:13

您的两个进程都有自己的两个信号量的副本,因为每个进程在实例化时都运行脚本中的整个代码。你知道吗

必须将信号量和队列定义移到if __name__ == '__main__':中,并将信号量的实例传递给ProducerConsumer构造函数,以便它们都使用三个对象的同一实例。你知道吗

from multiprocessing import Process, Semaphore, Lock, Queue
import time
from random import random

class Consumer(Process):
    def __init__(self, empty, full, buffer):
      super(Consumer, self).__init__()
      self.empty = empty
      self.full = full
      self.buffer = buffer

    def run(self):
        while True:
            time.sleep(4)
            print("Consumer: {}".format(self.full), flush=True)
            print("Consumer: buf {}".format(self.buffer.qsize()), flush=True)
            self.full.acquire()
            self.buffer.get()
            print('Consumer get', flush=True)
            time.sleep(1)
            self.empty.release()


class Producer(Process):
    def __init__(self, empty, full, buffer):
      super(Process, self).__init__()
      self.empty = empty
      self.full = full
      self.buffer = buffer

    def run(self):
        while True:
            self.empty.acquire()
            print ('Producer put ', flush=True)
            self.buffer.put('a') #<<<<<<<<<<< you forgot this in your code. If the queue is empty, get() will block on the consumer
            time.sleep(1)
            self.full.release()
            print(self.full, flush=True)


if __name__ == '__main__':
    buffer = Queue(10)
    empty = Semaphore(2)
    full = Semaphore(0)

    p = Producer(empty, full, buffer)
    c = Consumer(empty, full, buffer)
    p.daemon = c.daemon = True
    p.start()
    c.start()
    p.join()
    c.join()
    print ('Ended!')

相关问题 更多 >