You are on page 1of 8

Producer Consmner Assigmnent Notes - 1505

file:1 IIC:/Note%200flIo20Experiments.html

Thread CSE224 Operating Systems Lab Assignment

Producer Consumer Problem using POSIX Threads

Note: This HTML document is best viewed in Firfox and in Linux Platforms.

o Behaviour of the Queue System (Experiments)

o Answer to the question (a) and (b)

o Source Code

o Submission

Behaviour of the queue System

In this producer-consumer problem the behaviour of the queue soul ely depends on the parameters of the program itself. These parameters are :

• The number of producer thread

• The number of consumer thread

• The number of request

• The Queue Size

• The average arrival rate

• The average consuming rate

The description follows:

• The number of producer thread

The number of producer thread> number of consumer thread means that job production will be quicker than the job consumation, resulting in higher Queueing time (and tendency to make the queue full) and this higher Queuing Time will be resulting in a higher service time. The following outputs (one with higher producer thread one with equal) demonstrates this:

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate= Results:

Average Queue Time

Average Total Request Time Maximum queue length = 10

Parameter values: numproducer=5 numconsume Results:

Average Queue Time Average Total Request T' Maximum queue length = 1

• The Number of Consumer Thread If number of conumer thread > number of consuming rate is much much higher, the Queueing off queue very fast), resulting in a less service time. is barely prevalent. There are two demonstration (the number of consumer thread it is fast in completing the same '

10f8

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

maximum queue length.

file:1 IIC:/Note%200flIo20Experiments.html

45524072 useconds 56093629 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate=10 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 10

2086 useconds 10213459 useconds

Parameter values:

numproducer=l numconsumer=5 qsize=10 numrequest=100 arate=10 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 1

• Number of Request

Number of request bigger means generally the overall service time is bigger. Here are the result of 3 program execution. The first one is normal In the second one however accompanied by greater number of consumer threads, still taking much longer. And the third one shows that a good number of requests provided by the less number of consumer threads may fill up the queue (as shown the max queue length has increased).

12296847 useconds 21232900 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate=10 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 7

223697 useconds 996675550 useconds

Parameter values:

numproducer=l numconsumer=5 qsize=100 numrequest=10000 arate Results:

Average Queue Time

Average Total Request Time Maximum queue length = 1

80804434 useconds 1084857440 useconds

Parameter values:

numproducer=l numconsumer=2 qsize=10 numrequest=10000 arat Results:

Average Queue Time

Average Total Request Time Maximum queue length = 6

• Queue Size

The queue size affect the timings in a way that if resulting in higher queue time. With same number of the following two example demonstrate it.

Parameter values: numproducer=l numcons Results:

Average Queue Time Average Total Request Maximum queue length = 9

Parameter values: numproducer=l numconsumer=l Results:

Average Queue Time

Average Total Request Time

20f8

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

file:1 IIC:/Note%200flIo20Experiments.html

Maximum queue length

10

• The average producing rate (arate)

The higher average producing rate means jobs will be placed in the queue more frequently. If the consuming rate is not enough to cope up with this producing rate the queue time will increase and if the queue size is small enough the queue may get full, this will result in blocking the newly produced job, and ultimately increasing the total service time. The second one having higher arate, producing greater queue time as well as toal service time ( as total service time = queue time + consume time ).

61013508 useconds 71459075 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate=10 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 10

87986011 useconds 97663662 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate=20 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 10

• The average consuming rate (srate)

It is natural that the high consuming rate ( or service time that we made use of to uniform or randomize) results in a much lower Queue Time ( the jobs have to wait less in queue) resulting in less service time and reducing the maximum queue length . The following outputs show this fact (the first one is of normal srate while in the second the srate is double).

61013508 useconds 71459075 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate=10 Results:

Average Queue Time

Average Total Request Time Maximum queue length = 10

1518377 useconds 6697698 useconds

Parameter values:

numproducer=l numconsumer=l qsize=10 numrequest=100 arate= Results:

Average Queue Time

Average Total Request Time Maximum queue length = 4

Back to Top

The answer to the questions (a) and (b)

The relationship between A and !l :

If A <= ~ then then the queue length will remain finite. Con and larger.

Specifiying numproducer and numconsumer :

Clearly if numconsumer is greater than numproducer then the

Back to Top

The Source Code:

30f8

~S\E.RED V~

~0 ~

g;; ~

§ REGISTERED %

if A > ~ theYtt;«~(QUgrow larger ADDS NO

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

40f8

file:1 IIC:/Note%200flIo20Experiments.html

*

Producer-Conusmer Problem using POSIX thread

Author: Sayeed Mahmud

/

include include include include include include include

* compile with -lpthread */

define MAX PRODUCER 10
define MAX CONSUMER 10
-
define MAX REQRATE 100
define MAX CONSUMERATE 100
-
define MICRO 1000000 lass jobQueue{ private:

struct job{

struct timeval jobID struct job *next

typedef struct job JOB

JOB *curJob, *tail int count

int qsize ;

public:

jobQueue() {

curJob = tail count 0; qsize = 10 ;

NULL

-jobQueue() {

JOB* temp ;

while (curJob != NULL) { temp = curJob ;

curJob = curJob -> next free (curJob)

void produceJob(struct timeval jobID) { if (isFull()) return;

JOB *J = (JOB*)malloc(sizeof(JOB)) J->jobID = jobID

J->next = NULL ;

~S\E.RED V~

~0 ~

g;; ~

§ REGISTERED %

VERSION

if (curJob == NULL) { curJob J tail = J ;

}else{

tail->next = J ; tail = tail->next

count++

struct timeval consumeJob() { if (isEmpty()) NULL; struct timeval ret ; JOB* temp ;

if (curJob != NULL) {

ret = curJob->jobID temp = curJob ;

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

file:1 IIC:/Note%200flIo20Experiments.html

curJ

>next

free (temp) count-- ; return ret

bool isEmpty() {

return (count 0)

bool isFull() {

return (count

qsize)

void setQueueSize(int size) { qsize = size

int getQueueSize() { return qsize

int getQueueLength() { return count ;

* The Job Queue *1 lass jobQueue JQ

* the thread IDs *1

thread_t producer[MAX PRODUCER], consumer[MAX CONSUMER]

* mutexes *1 thread mutex t mut

PTHREAD MUTEX INITIALIZER

* the semaphore *1

* number of producer and consumer threads *1 numProducer = 1 ;

numConsumer = 1 ;

numRequest = 100 ;

* arrival rate and service rate and *1 nt avgArrivalTime, avgServiceTime reqProducedRate = 10 ; reqConsumedRate = 10 ; wakeUpProducer, wakeUpConsumer

* The ultimate Results *1 nsigned long long gQueueTime 0 nsigned long long gRequestTime nt maxQLen = -1 ;

II the Queue Time

o ; lithe total time

~S\E.RED v~

1-'0 ~~

§ REGISTERED %

VERSION ADDS NO WATERMARK e CJO

* These are some helper variables *1

nt reqConsumed 0 II the request consumed so nt reqProduced = 0 ; II the request produced so

* int uniform sleep time generator *1 nt uniform(int avg) {

return (rand() % (2 * avg))

* The Thread That produce new jobs id *producerThread(void *arg) {

int req ;

struct timeval T ; while (true) {

1* produced numRequest requests pthread_mutex lock(&mut)

50f8

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

60f8

file:1 IIC:/Note%200flIo20Experiments.html

== numRequest pthread_mutex unlock (&mut) break

reqProduced++ pthread_mutex unlock (&mut)

/* rest before hard work */ usleep(uniform(avgArrivalTime) )

gettimeofday(&T, NULL)

/* if Queue is full block and this blocking time contributes to the while (JQ.isFull())

/* place the job to the queue */ pthread_mutex_lock(&mut) JQ.produceJob(T)

if (maxQLen < JQ.getQueueLength()) maxQLen = JQ.getQueueLength() pthread_mutex unlock (&mut)

/* allow the consumer to unblock if it has been blocked due to empty sem_post(&sem)

return NULL ;

* The Thread That consumes jobs off the queue*/ id *consumerThread(void *arg) {

struct timeval T, recTime, qTime, fTime, sTime

while (true) {

/* if consumed numRequest requests no need for the loop */ pthread_mutex_lock(&mut)

if (reqConsumed == numRequest) { pthread_mutex unlock (&mut) break

reqConsumed++ pthread_mutex unlock (&mut)

/* waiting for the consumer thread to produce something */ sem wait(&sem)

/* Accessing the Queue so need to protect it from other threads */ pthread_mutex lock(&mut)

/* take a job from the queue for consuming*/ T = JQ.consumeJob()

pthread_mutex unlock (&mut)

gettimeofday(&recTime, NULL) //

qTime.tv_usec = recTime.tv sec

/* not sleeping -- servicing */ usleep(uniform(avgServiceTime) )

gettimeofday(&fTime, NULL) sTime.tv_usec = qTime.tv_usec sTime.tv usec -= (recTime.tv sec *

_ _

/* accessing global area -pthread_mutex_lock(&mut) gQueueTime += qTime.tv_usec gRequestTime += sTime.tv usec

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

70f8

file:1 IIC:/Note%200flIo20Experiments.html

mutex un

return NULL ;

001 parseCommandLine(int argc, char *argv[]) { char *temp, *t2 ;

int val ;

for (int i 1; i < argc ; i++) { temp = strtok(argv[i], "=") t2 = strtok (NULL, "=")

val = atoi(t2)

if (! strcmp ("numproducer", temp)) { if (val < 1 I I val > 10) {

printf("Parameter numproducer out of given range ( 1
return false
numProducer = val ;
}else if ( ! strcmp ("numconsumer", temp)) {
if (val < 1 I I val > 10) {
printf("Parameter numconsumer out of given range ( 1
return false numConsumer = val ;

) else if (! strcmp ("qsize", temp)) { if (val < 1) {

printf("Parameter qsize out of given range (1 - INF) return false

JQ.setQueueSize(val)

}else if (!strcmp("numrequest", temp)) { if (val < 10) {

printf("Parameter numrequest out of given range (1 - return false

numRequest = val ;
}else if ( ! strcmp ("arate", temp)) {
if (val < 1 I I val > 100) {
printf("Parameter arate out of given range ( 1 - 100)
return false ;
reqProducedRate = val ;
}else if ( ! strcmp ("srate", temp)) {
if (val < 1 I I val > 100) {
printf("Parameter srate out of given range ( 1 - 100)
return false ; reqConsumedRate = val ;

return true

nt main(int argc, char *argv[]) {

/* parse if Command Line argument present * if (argc > 1)

if (!parseCommandLine(argc, argv))

printf ("Parameter values: \n") printf("numproducer=%d numconsumer=%d qsi printf("numrequest=%d arate=%d srate=%d\n printf ("Resul ts: \n")

/* The attribute of our threads */ pthread_attr t attr

/* seeding random number generator */ srand(getpid() )

9/1112010 1:52 AM

Producer Consmner Assigmnent Notes - 1505

file:1 IIC:/Note%200flIo20Experiments.html

/* setting up avg arrival and service time */ avgArrivalTime (1 * MICRO) / reqProducedRate avgServiceTime = (1 * MICRO) / reqConsumedRate

/* initializing the semaphore */ sem_init(&sem, 0, 0)

/* definng our attributes */ pthread_attr_init(&attr)

pthread_attr setdetachstate(&attr, PTHREAD CREATE JOINABLE)

for (int i = 0 ; i < numProducer ; i++) pthread_create(&producer[i], &attr, producerThread, NULL)

for (int i = 0 ; i < numConsumer ; i++) pthread_create(&consumer[i], &attr, consumerThread, NULL)

pthread_attr destroy(&attr)

for (int i = 0 ; i < numConsumer ; i++) pthread_join(consumer[i], NULL) for (int i = 0 ; i < numProducer ; i++) pthread_join(producer[i], NULL)

printf("Average Queue Time = %llu useconds\n", gQueueTime)

printf("Average Total Request Time = %llu useconds\n", gRequestTime) printf ("Maximum queue length = %d\n", maxQLen)

return 0 ;

Submitted By:

Sayeed Mahmud Roll- 05 Batch - 15 2nd Year

Back to Top

80f8

~S\E.RED V~

~0 ~

g;; ~

§ REGISTERED %

VERSION

9/1112010 1:52 AM

You might also like