私は2つのpythonキューを扱います。
短い説明:
クライアントはwaiting queue
(q1)を通過し、その後(クライアント)が配信されます。 waiting queue
のサイズはN(プログラムでは10)を超えることはできません。 waiting queue
がいっぱいになると、クライアントはoutside queue
(q2、サイズ20)になります。外部キューがいっぱいになると、クライアントは拒否され、配信されません。
待機キューを残したすべてのクライアントは、外部キューからの別のクライアントが待機キューに参加できるようにします。あるキューから別のキューにアイテムを並べ替えることができません
キューの操作はスレッドセーフである必要があります。
以下、私が望むものをほぼ実装しました。しかし、私はこの問題に直面しています - 実行中に外部キュー(q1)から待機キュー(q2)にクライアントをエンキューします。serve
機能。私は何か重要なことを忘れてしまったと思います。私はこの文q1.put(client)
は永久にブロックすると思うが、理由を知らない。
import time
import threading
from random import randrange
from Queue import Queue, Full as FullQueue
class Client(object):
def __repr__(self):
return '<{0}: {1}>'.format(self.__class__.__name__, id(self))
def serve(q1, q2):
while True:
if not q2.empty():
client = q2.get()
print '%s leaved outside queue' % client
q1.put(client)
print '%s is in the waiting queue' % client
q2.task_done()
client = q1.get()
print '%s leaved waiting queue for serving' % client
time.sleep(2) # Do something with client
q1.task_done()
def main():
waiting_queue = Queue(10)
outside_queue = Queue(20)
for _ in range(2):
worker = threading.Thread(target=serve, args=(waiting_queue, outside_queue))
worker.setDaemon(True)
worker.start()
delays = [randrange(1, 5) for _ in range(100)]
# Every d seconds 10 clients enter to the waiting queue
for d in delays:
time.sleep(d)
for _ in range(10):
client = Client()
try:
waiting_queue.put_nowait(client)
except FullQueue:
print 'Waiting queue is full. Please line up in outside queue.'
try:
outside_queue.put_nowait(client)
except FullQueue:
print 'Outside queue is full. Please go out.'
waiting_queue.join()
outside_queue.join()
print 'Done'