css342: queues1 professor: munehiro fukuda. css342: queues2 topics basic concepts of queue queue...
TRANSCRIPT
CSS342: Queues 2
Topics
• Basic concepts of queue
• Queue implementation
• Queues used in– Applications– Operating Systems– Network
CSS342: Queues 3
Concepts of Queue• Queue of Bank Customers
– First-In First-Out (FIFO) service
– How can you estimate the average wait?– Solution: Simulate it using queues
Time = 0
Time = 12
Time = 20
Time = 38
Basic Concepts
CSS342: Queues 4
Queue Specificationclass Queue{public:
Queue( );Queue( const Queue& Q );~Queue( );bool isEmpty( ) const;bool enqueue( const Object &newItem );Object dequeue( );Object getFront( ) const;
}
retrieve the front itembut do not remove it
Unlike stacks: (aQueue.enqueue(newItem)).dequeue() is Not equal to aQueue unless it is empty.
dequeue( ): remove and get the front itemenqueue to the back
Basic Concepts
CSS342: Queues 5
STL Class queue
#include <queue>
queue( );Creates an empty queue. You can convert a list into a new stack. See your text pages 351 and 353Example: queue<int> aQueue;bool empty( ) const;Returns if the queue is empty.Example: while ( aQueue.empty( ) == false ) { … }size_type size( ) const;Returns the number of elements. Size_type is an integral type. You can compare it with an integer.Example: while (aQueue.size( ) > 0) { … }T &front( );Returns a reference to the first element.Example: while( !aQueue.empty() ) { cout << aQueue.front() << endl; aQueue.pop(); }T &back( );Returns a reference to the last element.Example: if( !aQueue.empty() ) cout << aQueue.front() << endl;void pop( );Removes the first element from the queue.Example: see the front( ) examplevoid push( const T& value );Inserts an item with value at the back of the queue.Example:stack<int> aQueue; for( int i=0; i < 10; i++ ) aQueue.push(i);
Basic Concepts
CSS342: Queues 6
STL Class queueExample
#include <queue>#include <iostream>using namespace std;
int main( ) { queue<int> aQueue; int item;
for ( int j = 0; j < 5; j++ ) aQueue.push( j );
while ( !aQueue.empty( ) ) { cout << aQueue.front( ) << endl; aQueue.pop( ); }}
Results:01234
Basic Concepts
CSS342: Queues 7
Queue Implementation
• We learned how to use the queue. Then how can we implement it?– Array-based implementation– Pointer-based implementation– Reuse of linked lists
Implementation
CSS342: Queues 8
An Array-Based Implementation(Naïve Implementation)
k …..7…..142back 0 1 2 k theArray.size( )-1
0front
49 10 7…..back 0 1 2
theArray.size( )-1
47front
447 48 49
template<class Object>class Queue{public:
Queue( );…..;
private:vector<Object> theArray;int front;int back;
}
Problem: rightward driftShift array elements to the left is costly.
Implementation
CSS342: Queues 9
An Array-Based Implementation(A Circular Array Implementation)
template <class Object>class Queue{public:
Queue( );bool isEmpty( ) const;const Object getfront( ) const;void flush( );Object dequeue( );void enqueue( const Object &newItem );
Private:Vector<Object> theArray;int front;int back;int currentSize: // number of items in queue
void doubleQueue( ); // make the size of theArray double}
24
1
7
0
1
2
3
theArray.size( )-1 front
backInvariant: front should not pass more than 1 item ahead from back.
back should not pass front since it has been passed by frontTo guarantee that, count keeps track of #items in queue: currentSize
Implementation
CSS342: Queues 10
A Circular Array Implementationtemplate<class Object> void Queue<Object>::flush( ) { currentSize = 0; front = 0; back = theArray.size( ) – 1;}
template<class Object>Queue<Object>::Queue( ) : theArray( 1 ) { flush( );}
template<class Object>bool Queue<Object>::isEmpty( ) const { return currentSize == 0;}
template<class Object>void Queue<Object>::doubleQueue( ) { theArray.resize( theArray.size( ) * 2 + 1 ); // in case theArray.size( ) was 0 if ( front != 0 ) { for ( i = 0; i < front; i++ ) theArray[i + currentSize ] = theArray[ i ]; back += currentSize; }}
0
1
2
3
theArray.size( )-1
frontback back
Implementation
CSS342: Queues 11
A Circular Array Implementation
template <class Object>const Object Queue<Object>::getFront( ) { if ( isEmpty( ) ) throw “empty queue”; return theArray[front];}
template <class Object>void Queue<Object>::enqueue( const Object &newItem ) { if ( currentSize == theArray.size( ) ) doubleQueue( ); back = ++back % theArray.size( ); items[back] = newItem; ++currentSize;}
template <class Object>Object Queue<Object>::dequeue( ) { Object frontItem = getFront( ); currentSize--; front = ++front % theArray.size( ); return frontItem;}
0
1
2
theArray.size( )
76
front
back
Implementation
CSS342: Queues 12
A Circular Array Implementation0
1
2
3
MAX_Q-1
30
1
2
3
MAX_Q-1
0
1
2
MAX_Q-1
76
0
1
2
3
MAX_Q-1
76
389
2
41
enqueue(7)enqueue(6)
enqueue(3)enqueue(8)enqueue(9)enqueue(2)enqueue(4)enqueue(1)
dequeue()dequeue()dequeue()dequeue()dequeue()dequeue()dequeue()dequeue()
(1) (2)
(3) (4)
Initial state
count=0count=2
count=8 count=0
frontback front
back
back
frontback front
Implementation
CSS342: Queues 13
A Pointer-Based Implementation
2 4 1 7
front back
NULL
template <class Object>class Queue { public: Queue( ) : front( NULL ), back( NULL ); Queue( const Queue &rhs ); ~Queue( );
bool isEmpty( ) const; const Object getFront( ) const; void flush( ); Object dequeue( ); void enqueue( const Object &newItem ); private: struct QueueNode { Object item; QueueNode *next; }; QueueNode *front; QueueNode *back;}
Implementation
CSS342: Queues 14
A Pointer-Based Implementation (deuque)
2
4 1 7
front
back
NULL
template<class Object>Bool Queue<Object>::isEmpty( ) const { return front == NULL;}template<class Object>const Queue Queue<Object>::getFront( ) const { if ( isEmpty( ) ) throw “empty queue”; return front->item;}
template<class Object>Object Queue<Object>::dequeue( ) { Object frontItem = getFront( ); Queue *old = frontPtr; if (front == back) { front = NULL; back = NULL; } else front = front->next; delete old; return frontItem;}
back
NULL
front
NULL NULL
Implementation
CSS342: Queues 15
2
4 1 2
front
back
NULL
template<class Object>void Queue<Object>::enqueue( const Ojbect& newItem ) { QueueNode *newPtr = new QueueNode; if ( newPtr == NULL ) throw “out of memory”; newPtr->item = newItem; newPtr->next = NULL; if (isEmpty( )) frontPtr = newPtr; else backPtr->next = newPtr; backPtr = newPtr;}
back
NULL
front
A Pointer-Based Implementation (enqueue)
NULLNULL
NULL
Implementation
CSS342: Queues 16
A Pointer-Based Implementation (copy constructor)
2 4 1 7front back
NULL
template <class Object>Queue<Object>::Queue( const Queue<Object> &rhs ) { front = back = NULL; *this = rhs;}
template <class Object>Queue<Object>::operator=( const Queue<Object> &rhs ) { if ( this != &rhs ) { flush( ); for ( QueueNode rptr = rhs.front; rptr != NULL; rptr = rptr->next ) enqueue( rptr->item ); } return *this;}
rhs:
lhs: 2 4 1 7 NULL
front back
Easier than stack!
void Queue<Object>::flush( ) { while ( !isEmpty( ) ) dequeue( );}
Implementation
CSS342: Queues 17
Implementation by List Reuse• Why not reuse the Linked List class we studied?• Contain a linked list instance in our stack implementation
Implementation
#include <iostream>#include "llist.h“
template<class Object>class Queue { public: // the same as previous private: LList<Object> list;};
template<class Object>bool Stack<Object>::isEmpty( ) const { return list.isEmpty( );}
template<class Object>const Object Stack<Object>::getFront( ) const { return list.retrieve( 1 ); // retrieve 1st list item}
template<class Object>void Stack<Object>::flush( ) { return list.clear( );}
Consider by yourself about an implementation of Queue( const Queue &rhs ), enqueue( Object &newItem ), and dequeue( )
queue.h queue.cpp
CSS342: Queues 18
A Summary of Position-Oriented ADTsStack Queue List
Check data existence
isEmpty isEmpty getLength
Insert a new data item
push to top enqueue to back insert anywhere
Delete a specific data item
pop from top dequeue from top delete from any position
Retrieve a data item getTop getFront Retrieve any item
Then, why do we need stacks and queues?
Implementation
Comparing Implementations
Completely the same as Stack.
CSS342: Queues 20
Example 1: Palindromes
Check if an input string is a parindrome:
abcdedcba
1. Push and enqueue each of them to a stack and a queue.
abcdedcba
front back
Queue
enqueue abcdedcba
top
Stack
push
2. Pop and dequeue each from the stack and the queue, and compare them
abcdedcba
front back
Queue
dequeue abcdedcba
top
Stack
pop
Queues in Applications
CSS342: Queues 21
Example 1: Palindromesint main( int argc, char *argv[] ) { queue<char> cQueue; stack<char> cStack;
if ( argc != 2 ) { cerr << "usage: " << argv[0] << " string" << endl; return -1; } for ( int i = 0; argv[1][i] != '\0'; i++ ) { cQueue.push( argv[1][i] ); cStack.push( argv[1][i] ); }
while ( !cQueue.empty( ) ) { if ( cQueue.front( ) != cStack.top( ) ) { cout << "not a palindrome" << endl;
return -2; } cQueue.pop( ); cStack.pop( ); } if ( !cStack.empty( ) ) { cout << "not a palindrome" << endl; return -2; } cout << "a palindrome" << endl; return 0;}
Queues in Applications
CSS342: Queues 22
Example 2: Computer Simulation
• Simulating the average waiting time of clients being served by servers– Banking service: clients = customers, servers = bank clerks
– Car wash: clients = cars, servers = gas stations
– Computer system: clients = processes, servers = CPUs
– Network simulation: clients = packets, servers = routers
Time = 20
Queues in Applications
CSS342: Queues 23
Computer SimulationClient.h
class Client { public: Client( ) : arrivalTime( 0 ) { }; Client( int time ) : arrivalTime( time ) { }; int getArrivalTime ( ) { return arrivalTime; }; private: int arrivalTime;};
Time = 12
Queues in Applications
CSS342: Queues 24
Computer SimulationServer.h
#include <queue>#include <iostream>Using namespace std;class Server { public: Server( ) : currentTime( 0 ), numberOfClients( 0 ), sumOfWaitingTime( 0 ), nextDepartureTime( INF ) { } void runSimulation( ); void printResult( ); private: const static int INF = 10000; const static int SERVICE_TIME = 10; int currentTime; int nextDepartureTime; int numberOfClients; int sumOfWaitingTime; queue<Client> clientQueue;
void newArrival( int newArrivalTime ); void giveService( );};
Time = 20
Time = 38
Queues in Applications
CSS342: Queues 25
Computer SimulationServer.cpp
#include “Server.h”
void Server::newArrival( int newArrivalTime ) { currentTime = newArrivalTime; numberOfClients++; // increments the total number of clients served cout << "Time=" << newArrivalTime << ": a new client has arrived" << endl; if ( nextDepartureTime == INF ) { // no one is being served at the beginning nextDepartureTime = currentTime + SERVICE_TIME; cout << "Time=" << nextDepartureTime << ": a client arrived at "
<< currentTime << " has served" << endl; // serve him/her immediately } else clientQueue.push( Client( newArrivalTime ) ); // someone is being served} // a new client should wait.
void Server::giveService( ) { currentTime = nextDepartureTime; // start serving the next person if ( !clientQueue.empty( ) ) { // from the queue Client client = clientQueue.front( ); clientQueue.pop( ); sumOfWaitingTime += currentTime - client.getArrivalTime( ); // calculate the waiting time nextDepartureTime = currentTime + SERVICE_TIME; // schedule the time to get
// finished with serving him/her cout << "Time=" << nextDepartureTime << ": a client arrived at "
<< client.getArrivalTime( ) << " has served" << endl; } else nextDepartureTime = INF;}
Queues in Applications
CSS342: Queues 26
Computer SimulationServer.cpp (Cont’d)
void Server::runSimulation( ) { int SENTINEL = 999; int newArrivalTime;
cin >> newArrivalTime; while ( newArrivalTime != SENTINEL ) { if ( newArrivalTime < nextDepartureTime ) { newArrival( newArrivalTime ); cin >> newArrivalTime; } else giveService( ); }
while ( nextDepartureTime < INF ) giveService( );}
void Server::printResult( ) { if ( numberOfClients == 0 ) cout << "No client requested a service" << endl; else cout << "avarage waiting time = "
<< double( sumOfWaitingTime ) / double ( numberOfClients ) << endl;}
Time = 20
Time = 38
Time = 50
Time = 38
Queues in Applications
CSS342: Queues 27
Computer Simulationdriver.cpp and execution
Queues in Applications
#include "Server.h"
int main( ) { Server s; s.runSimulation( );}
[mfukuda@perseus simulation]$ a.out10Time=10: a new client has arrivedTime=20: a client arrived at 10 has served15Time=15: a new client has arrived17Time=17: a new client has arrived22Time=30: a client arrived at 15 has servedTime=22: a new client has arrived999Time=40: a client arrived at 17 has servedTime=50: a client arrived at 22 has servedavarage waiting time = 9[mfukuda@perseus simulation]$
New Arrival 10 15 17 22 999
numberOfClients 0 1 2 3 4
currentTime 0 10 15 17 20 22 30 40
nextDepartureTime INF 10+10=20 20 20 20 + 10 = 30 30 30 + 10 = 40 40 + 10 = 50
Queue empty empty 15 15 17 17 17 22 22
sumOfWaitingTime 0 0 0 0 0 + 20 - 15 = 5 5 5 + 30 - 17 = 18 18 + 40 - 22 = 36
ave. waiting time 36/4 = 9
A larger value
A smaller value
CSS342: Queues 28
1cell/time unit1cell/2.4 time units
1cell/8 time units
Discrete Event Computer SimulationQueues in Applications
CSS342: Queues 29
f2
f5 f6
f4f3
f7
f11f10f9f8 f12
f1
s16
attack
attack
t2.4
s8
t4.8 t7.2X deleted
Xdeleted
Discrete Event Computer Simulation
f1 t2.4 s8 f2 t2.4 s8 f3t2.4 s8 f3 t4.8 s8
f4 t4.8 s8 f5t4.8 s8 f5 t7.2 s8 f6 s8
Time = 1 Time = 2 Time = 2.4 Time = 3
Time = 6Time = 5Time = 4.8Time = 4
Queues in Applications
CSS342: Queues 30
• Priority queues:– The front item is always the smallest.
• Three types where O(1) search for the front item:– Queues with insertion sort: O(N) search/insertion– Skip lists: O(log N) search/insertion– Binary search trees and heaps: O(log N)
search/insertion
Discrete Event Computer SimulationQueues in Applications
CSS342: Queues 31
Very Large IntegerDefinition
• RSA (public/private key) encryption – Picks up two prime numbers p and q, each 256 bits.
– Finds e whose GCD with (p – 1)(q – 1) is 1.
– Encrypts m with me % (p * q)
– Descrypts c with cd % (p * q), • where d = e-1mod ((p - 1) x (q - 1))
• How can we represent p, q, e, d, me, and cd?– Represent an integer with a queue of digits
Queues in Applications
1 9 4 8 7
a variable length of digits in a queue
CSS342: Queues 32
Very Large IntegerArithmetic Operations
• Addition: + • Subtraction: –
Queues in Applications
1
5
0
7
8
digit i+1 digit i
lhs:
rhs:+
+
result:
4
3
+
+
8
carry: 1
9
0
7
8
digit i+1 digit i
lhs:
rhs:–
–
result:
4
3
–
–
0
borrow:
Enqueue digits to the tail upon a user input.Dequeue digits from the tail upon an arithmetic operation.Enqueue results from the front.
CSS342: Queues 33
Very Large IntegerDeque
Queues in Applications
74
template <class Object>class Deque { public: Deque( ); Deque( const Deque &rhs ); ~Deque( );
bool isEmpty( ) const; // checks if a deque is empty. int size( ) const; // retrieves # deque nodes const Object &getFront( ) const; // retrieve the front node const Object &getBack( ) const; // retrieve the tail node
void clear( ); // clean up all deque entries. void addFront( const Object &obj ); // add a new node to the front void addBack( const Object &obj ); // add a new node to the tail Object removeFront( ); // remove the front node Object removeBack( ); // remove the tail node
const Deque &operator=( const Deque &rhs ); // assignment
private: struct DequeNode { // a deque node Object item; DequeNode *next; DequeNode *prev; }; DequeNode *front; DequeNode *back;};
9
CSS342: Queues 35
Unix Message Queues
struct mymesg { long mytype; char mtext[512];} message_body;
int main( void ) { int msgid = msgget( 100, IPC_CREAT ); strcpy( message_body.mtext, “hello world\n” ); msgsnd( msgid, &message_body, 512, 0 );}
struct mymesg { long mytype; char mtext[512];} message_body;
int main( void ) { int msgid = msgget( 100, IPC_CREAT ); msgrcv( msgid, &message_body, 512, 0, 0 ); cout << message_body.mtext << endl;}
Message queue(id = msgid)
0 1 2 Some other process canenqueue and dequeue a message
Queues in OS
CSS342: Queues 36
Multilevel Queue Scheduling
• Each queue has its own scheduling algorithm, – foreground
(interactive) – RR, 80% CPU time
– background (batch) – FCFS, 20% CPU time
Queues in OS
CSS342: Queues 37
Multilevel Feedback-Queue Scheduling
• A new job enters queue Q0 which is served FCFS. When it gains CPU, job receives 8 milliseconds. If it does not finish in 8 milliseconds, job is moved to queue Q1.
• At Q1 job is again served FCFS and receives 16 additional milliseconds. If it still does not complete, it is preempted and moved to queue Q2.
Queues in OS
CSS342: Queues 39
packet
Flow Control
Sending application Receiving application
Send Socket Buffer Receive Socket Buffer
packet packet
packet
packet
send
ack
Xread blocked
Application is slow to read.
Xpacket droppedpacket retransmitted
Xpacket droppedpacket retransmitted
Xwrite blocked
Queues in Network