Professional Documents
Culture Documents
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