40
CSS342: Queues 1 CSS342: Queues Professor: Munehiro Fukuda

CSS342: Queues1 Professor: Munehiro Fukuda. CSS342: Queues2 Topics Basic concepts of queue Queue implementation Queues used in –Applications –Operating

Embed Size (px)

Citation preview

CSS342: Queues 1

CSS342: Queues

Professor: Munehiro Fukuda

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 19

Queues in Applications

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 34

Queues in OS

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 38

Queues in Network

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

CSS342: Queues 40

Congestion in Packet-Switched Network

• Source cannot directly observe the traffic on the slow network

Destination1.5-Mbps T1 link

Router

Source2

Source1

100-Mbps FDDI

10-Mbps Ethernet

Flow 1

Flow 2

Flow 3

Flow 4

Round-robinservice

Queues in Network