我正在尝试用Python实现生产者-消费者场景。。。 如果队列已满,生产者应该停止锁定变量,如果队列未满,则释放它。。。我在循环中使用lock变量
def run(self):
#mutexProducer.acquire()
#Entering Critical section
#print self.queue.qsize()
while True:
customer=Customer()
self.mutex.acquire()# acquire condition variable to see if queue is full
if self.queue.full():
print "Queue is full : Cant Enter Critical Section"
#print "Customer %d is discarded" %(customer.id)
elif not self.queue.full() :
print "i am here"
print self.mutex.release()
self.mutex.acquire()
#Critical Section
self.queue.put(customer)#pushing Customer to queue
print "Customer %d Enters the Queue with %d service " %(customer.id,customer.serviceTime)
#critical Section
self.mutex.release()
我的代码一遍又一遍地锁定多个实例吗??我问的原因是我对线程还不熟悉,当队列满了之后,生产者停止创建任何进程(在我的例子中是客户)
我在你的代码中添加了一些注释,这有一些问题:
除了注1之外(但动机相同):
我真的不明白这是逻辑。您释放了锁,允许线程检查队列,而其他线程推送到队列,但您认为队列不是线程安全的。
如果使用的是队列的线程安全性,那么为什么首先使用互斥锁?
编辑:主要问题是,正如指定的那样,您要与生产者获取两次互斥量。只能获取互斥对象一次(至少当它是
threading.Lock
对象时)。在您的对讲机中尝试以下代码:看看会发生什么。
不管怎样,找出关键部分的逻辑。固定代码(注意1)应该可以防止由于在第一个if分支上没有释放互斥锁而导致的阻塞。
祝你好运。
使用
Lock
的最佳方法是使用with语句。它自动处理锁的获取和释放,即使块因异常而退出。例如:
如果不进行新的小修改,就不可能将with语句替换到代码中。但是,这通常反映了应该如何使用锁。
但是,由于有多个相关的关键部分,如果有多个生产者线程,就会出现问题。如果一个线程检查队列的状态,退出其关键部分,挂起以支持另一个线程,并且在恢复执行时队列已满,会发生什么情况。在前面的关键部分中检查的条件不再适用。因此,所有相关的行动必须在同一个关键部分一起完成。如果只有一个生产者,那么这就不是问题。
应对多个生产商:
查看了您的注释中提供的代码here。我可以看出你没有正确使用锁。每个协调线程必须具有对同一锁的访问权限,而不是为每个线程创建新的单独锁。
你的主要方法应该是:
相关问题 更多 >
编程相关推荐