Last active
May 18, 2016 06:05
-
-
Save discort/ad5469d17202f0884a05a6723f8cd579 to your computer and use it in GitHub Desktop.
Cannot to line up item from one queue to another
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding:utf8 -*- | |
import time | |
import threading | |
import logging | |
from Queue import Queue, Full as FullQueue | |
from random import randrange | |
logging.basicConfig(level=logging.DEBUG, | |
format='%s(asctime)s (%(threadName)-2s) %(message)s') | |
WAITING_ROOM_SIZE = 10 # Размер очереди в зале ожидания | |
OUTDOOR_PLACE_SIZE = 20 # Размер очереди на улице | |
DELAY_INTERVAL = (1, 10) # Интервал времени обслуживания одного клиента в секундах | |
class Client(object): | |
def __init__(self, ident): | |
self.ident = ident | |
def __repr__(self): | |
return '<{0}: {1}>'.format(self.__class__.__name__, self.ident) | |
class MaintenanceService(object): | |
def __init__(self): | |
# Зал ожидания, через который проходят клиенты к рабочему месту обслуги | |
self.waiting_room = Queue.Queue(WAITING_ROOM_SIZE) | |
def service(self): | |
while True: | |
client = self.waiting_room.get() | |
self.service_client(client) | |
self.waiting_room.task_done() | |
def service_client(self, client): | |
delay = randrange(*DELAY_INTERVAL) | |
time.sleep(delay) | |
def add_to_waiting_room(self, client): | |
try: | |
self.waiting_room.put_nowait(client) | |
logging.debug('Client: %s has been entered to the waiting room' % client) | |
except Queue.Full: | |
# Очередь на улице. В неё попадают те клиенты, | |
# которые не вместились в зал ожидания | |
self.outdoor_place = Queue.Queue(OUTDOOR_PLACE_SIZE) | |
self.add_to_outdoor_place(client) | |
def add_to_outdoor_place(self, client): | |
try: | |
self.outdoor_place.put_nowait(client) | |
logging.debug('Waiting room is full. Client: %s on the outdoor place' % client) | |
except Queue.Full: | |
logging.warn('Client: %s is unserviced' % client) | |
def serve(q1, q2, mutex): | |
while True: | |
client = q1.get() | |
print '%s leaved waiting queue for serving' % client | |
time.sleep(2) # Do something with client | |
q1.task_done() | |
with mutex: | |
if not q2.empty() and not q1.full(): | |
client = q2.get() | |
print '%s leaved outside queue' % client | |
q1.put(client) | |
print '%s is in the waiting queue' % client | |
q2.task_done() | |
def main(): | |
waiting_queue = Queue(WAITING_ROOM_SIZE) | |
outside_queue = Queue(OUTDOOR_PLACE_SIZE) | |
lock = threading.RLock() | |
for _ in range(2): | |
worker = threading.Thread(target=serve, args=(waiting_queue, outside_queue, lock)) | |
worker.setDaemon(True) | |
worker.start() | |
# Every 1-5 seconds 10 clients enter to the waiting room | |
i = 1 | |
while True: | |
delay = randrange(1, 5) | |
time.sleep(delay) | |
for _ in range(10): | |
client = Client(i) | |
try: | |
lock.acquire() | |
if not waiting_queue.full(): | |
waiting_queue.put(client) | |
else: | |
outside_queue.put_nowait(client) | |
except FullQueue: | |
# print 'Outside queue is full. Please go out.' | |
pass | |
finally: | |
lock.release() | |
i += 1 | |
waiting_queue.join() | |
outside_queue.join() | |
print 'Done' | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment