程序还有点小bug
mian.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include "coursework.h"
typedef struct process* PNode;
typedef struct
{
PNode q_front;
PNode q_rear;
int q_size;
pthread_mutex_t q_lock;
}Queue;
/*构造一个空队列*/
Queue *InitQueue()
{
Queue *pqueue = (Queue *)malloc(sizeof(Queue));
if(pqueue!=NULL)
{
pqueue->q_front = NULL;
pqueue->q_rear = NULL;
pqueue->q_size = 0;
pthread_mutex_init(&pqueue->q_lock, NULL);
}
return pqueue;
}
/*队头元素出队*/
PNode DeQueue(Queue *pqueue)
{
PNode ret = NULL;
pthread_mutex_lock(&pqueue->q_lock);
if(pqueue->q_size>0) {
ret=pqueue->q_front;
pqueue->q_size--;
pqueue->q_front = pqueue->q_front->oNext;
if(pqueue->q_size==0){
pqueue->q_rear = NULL;
pqueue->q_front=NULL;
}
}
pthread_mutex_unlock(&pqueue->q_lock);
return ret;
}
/*销毁一个队列*/
void DestroyQueue(Queue *pqueue)
{
if(!pqueue)
return;
while(pqueue->q_size!=0) {
DeQueue(pqueue);
}
pthread_mutex_destroy(&pqueue->q_lock);
free(pqueue);
pqueue = NULL;
}
/*将新元素入队*/
PNode EnQueue(Queue *pqueue, PNode pnode)
{
if(pnode != NULL) {
pthread_mutex_lock(&pqueue->q_lock);
if(pqueue->q_size==0) {//kong
pqueue->q_front = pnode;
} else {
pqueue->q_rear->oNext = pnode;
}
pqueue->q_rear = pnode;
pqueue->q_size++;
pthread_mutex_unlock(&pqueue->q_lock);
}
return pnode;
}
struct OK_NUM
{
int num;
pthread_mutex_t lock;
}ok_num;
void InitOk()
{
ok_num.num=0;
pthread_mutex_init(&ok_num.lock, NULL);
}
int ask_ok(){
if(ok_num.num>=10)return 1;
return 0;
}
void add_ok(){
pthread_mutex_lock(&ok_num.lock);
ok_num.num++;
pthread_mutex_unlock(&ok_num.lock);
}
sem_t empty;
Queue* q;
struct consumerId{
int iConsumerId;
}Consumer;
int all_turnround=0,all_response;
void *consumer(void *arg){
int id = *((int *)arg);
PNode temp ;
do{
temp = DeQueue(q);
if(temp==NULL)continue;
struct timeval oEndTime;
gettimeofday(&oEndTime, NULL);
int previousTime = temp-> iBurstTime;
simulateRoundRobinProcess(temp, &temp -> oTimeCreated, &oEndTime);
printf("Consumer ID = %d, Process Id = %d, Previous Burst Time = %d, New Burst Time = %d", \
id, temp-> iProcessId, previousTime, temp-> iBurstTime);
if(temp -> iState == FINISHED){
int a=getDifferenceInMilliSeconds(temp->oTimeCreated,oEndTime);
printf(", Turn Around Time = %d",a);
add_ok();
all_turnround+=a;
free(temp);
temp=NULL;
sem_post(&empty);
}else{
EnQueue(q,temp);
}
printf("\r\n");
if(ask_ok())break;
}while(1);
exit(0);
}
void *producer(void *args){
PNode tmp_data;
static int count_process=0;
while(1){
sem_wait(&empty);
tmp_data = generateProcess();
EnQueue(q,tmp_data);
count_process++;
if(count_process>=10){
break;
}
}
exit(0);
}
int main()
{
InitOk();
sem_init(&empty, 0, BUFFER_SIZE);
q=InitQueue();
// pthread_t thrd_prod, thrd_cons[NUMBER_OF_CONSUMERS];
pthread_t thrd_prod, thrd_cons0, thrd_cons1, thrd_cons2, thrd_cons3, thrd_cons4;
struct consumerId consumer0;
struct consumerId consumer1;
struct consumerId consumer2;
struct consumerId consumer3;
struct consumerId consumer4;
consumer0.iConsumerId = 0;
consumer1.iConsumerId = 1;
consumer2.iConsumerId = 2;
consumer3.iConsumerId = 3;
consumer4.iConsumerId = 4;
pthread_create(&thrd_prod, NULL, producer, NULL);
pthread_create(&thrd_cons0, NULL, consumer, &consumer0);
pthread_create(&thrd_cons1, NULL, consumer, &consumer1);
pthread_create(&thrd_cons2, NULL, consumer, &consumer2);
pthread_create(&thrd_cons3, NULL, consumer, &consumer3);
pthread_create(&thrd_cons4, NULL, consumer, &consumer4);
pthread_join(thrd_prod, NULL);
pthread_join(thrd_cons0, NULL);
pthread_join(thrd_cons1, NULL);
pthread_join(thrd_cons2, NULL);
pthread_join(thrd_cons3, NULL);
pthread_join(thrd_cons4, NULL);
printf("Average turn around time = %f",(double)all
coursework.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include "coursework.h"
typedef struct process* PNode;
typedef struct
{
PNode q_front;
PNode q_rear;
int q_size;
pthread_mutex_t q_lock;
}Queue;
/*构造一个空队列*/
Queue *InitQueue()
{
Queue *pqueue = (Queue *)malloc(sizeof(Queue));
if(pqueue!=NULL)
{
pqueue->q_front = NULL;
pqueue->q_rear = NULL;
pqueue->q_size = 0;
pthread_mutex_init(&pqueue->q_lock, NULL);
}
return pqueue;
}
/*队头元素出队*/
PNode DeQueue(Queue *pqueue)
{
PNode ret = NULL;
pthread_mutex_lock(&pqueue->q_lock);
if(pqueue->q_size>0) {
ret=pqueue->q_front;
pqueue->q_size--;
pqueue->q_front = pqueue->q_front->oNext;
if(pqueue->q_size==0){
pqueue->q_rear = NULL;
pqueue->q_front=NULL;
}
}
pthread_mutex_unlock(&pqueue->q_lock);
return ret;
}
/*销毁一个队列*/
void DestroyQueue(Queue *pqueue)
{
if(!pqueue)
return;
while(pqueue->q_size!=0) {
DeQueue(pqueue);
}
pthread_mutex_destroy(&pqueue->q_lock);
free(pqueue);
pqueue = NULL;
}
/*将新元素入队*/
PNode EnQueue(Queue *pqueue, PNode pnode)
{
if(pnode != NULL) {
pthread_mutex_lock(&pqueue->q_lock);
if(pqueue->q_size==0) {//kong
pqueue->q_front = pnode;
} else {
pqueue->q_rear->oNext = pnode;
}
pqueue->q_rear = pnode;
pqueue->q_size++;
pthread_mutex_unlock(&pqueue->q_lock);
}
return pnode;
}
struct OK_NUM
{
int num;
pthread_mutex_t lock;
}ok_num;
void InitOk()
{
ok_num.num=0;
pthread_mutex_init(&ok_num.lock, NULL);
}
int ask_ok(){
if(ok_num.num>=10)return 1;
return 0;
}
void add_ok(){
pthread_mutex_lock(&ok_num.lock);
ok_num.num++;
pthread_mutex_unlock(&ok_num.lock);
}
sem_t empty;
Queue* q;
struct consumerId{
int iConsumerId;
}Consumer;
int all_turnround=0,all_response;
void *consumer(void *arg){
int id = *((int *)arg);
PNode temp ;
do{
temp = DeQueue(q);
if(temp==NULL)continue;
struct timeval oEndTime;
gettimeofday(&oEndTime, NULL);
int previousTime = temp-> iBurstTime;
simulateRoundRobinProcess(temp, &temp -> oTimeCreated, &oEndTime);
printf("Consumer ID = %d, Process Id = %d, Previous Burst Time = %d, New Burst Time = %d", \
id, temp-> iProcessId, previousTime, temp-> iBurstTime);
if(temp -> iState == FINISHED){
int a=getDifferenceInMilliSeconds(temp->oTimeCreated,oEndTime);
printf(", Turn Around Time = %d",a);
add_ok();
all_turnround+=a;
free(temp);
temp=NULL;
sem_post(&empty);
}else{
EnQueue(q,temp);
}
printf("\r\n");
if(ask_ok())break;
}while(1);
exit(0);
}
void *producer(void *args){
PNode tmp_data;
static int count_process=0;
while(1){
sem_wait(&empty);
tmp_data = generateProcess();
EnQueue(q,tmp_data);
count_process++;
if(count_process>=10){
break;
}
}
exit(0);
}
int main()
{
InitOk();
sem_init(&empty, 0, BUFFER_SIZE);
q=InitQueue();
// pthread_t thrd_prod, thrd_cons[NUMBER_OF_CONSUMERS];
pthread_t thrd_prod, thrd_cons0, thrd_cons1, thrd_cons2, thrd_cons3, thrd_cons4;
struct consumerId consumer0;
struct consumerId consumer1;
struct consumerId consumer2;
struct consumerId consumer3;
struct consumerId consumer4;
consumer0.iConsumerId = 0;
consumer1.iConsumerId = 1;
consumer2.iConsumerId = 2;
consumer3.iConsumerId = 3;
consumer4.iConsumerId = 4;
pthread_create(&thrd_prod, NULL, producer, NULL);
pthread_create(&thrd_cons0, NULL, consumer, &consumer0);
pthread_create(&thrd_cons1, NULL, consumer, &consumer1);
pthread_create(&thrd_cons2, NULL, consumer, &consumer2);
pthread_create(&thrd_cons3, NULL, consumer, &consumer3);
pthread_create(&thrd_cons4, NULL, consumer, &consumer4);
pthread_join(thrd_prod, NULL);
pthread_join(thrd_cons0, NULL);
pthread_join(thrd_cons1, NULL);
pthread_join(thrd_cons2, NULL);
pthread_join(thrd_cons3, NULL);
pthread_join(thrd_cons4, NULL);
printf("Average turn around time = %f",(double)all
coursework.h
#include <stdlib.h>
#include <sys/time.h>
#include "coursework.h"
#include <stdio.h>
int iPid = 0;
/*
* Function generates asingle job and initialise the fields. Processs will have a increasing job id, reflecting the order in which they were created.
* Note that the objects returned are allocated in dynamic memory, and that the caller is responsible for free-ing the memory when it is no longer in use.
*
* REMARK: note that the random generator will generate a fixed sequence of random numbers. I.e., every time the code is run, the times that are generated will be the same, although the individual
* numbers themselves are "random". This is achieved by seeding the generator (by default), and is done to facilitate debugging if necessary.
*/
struct process * generateProcess()
{
struct process * oTemp = (struct process *) malloc (sizeof(struct process));
if(oTemp == NULL)
{
printf("Malloc Failed\n");
exit(-1);
}
oTemp->iProcessId = iPid++;
oTemp->iBurstTime = (rand() % MAX_BURST_TIME) + 1;
gettimeofday(&(oTemp->oTimeCreated), NULL);
oTemp->iState = NEW;
oTemp->oNext = NULL;
return oTemp;
}
/*
* Function returning the time difference in milliseconds between the two time stamps, with start being the earlier time, and end being the later time.
*/
long int getDifferenceInMilliSeconds(struct timeval start, struct timeval end)
{
long int iSeconds = end.tv_sec - start.tv_sec;
long int iUSeconds = end.tv_usec - start.tv_usec;
long int mtime = (iSeconds * 1000 + iUSeconds / 1000.0);
return mtime;
}
/*
* Function to call when simulating a round robin job. This function will:
* - calculate the (remaining) burst time
* - set the state to running
* - run the job
* - reduce the burst time of the process with the time that it ran
* - change the state to finished if the burst time reaches 0, set it to ready if the process used its entire time slice and was taken off the CPU
*/
void simulateRoundRobinProcess(struct process * oTemp, struct timeval * oStartTime, struct timeval * oEndTime)
{
long int iDifference = 0;
int iBurstTime = oTemp->iBurstTime > TIME_SLICE ? TIME_SLICE : oTemp->iBurstTime;
oTemp->iState = RUNNING;
runProcess(iBurstTime, oStartTime, oEndTime);
oTemp->iBurstTime -= iBurstTime;
if(oTemp->iBurstTime == 0)
oTemp->iState = FINISHED;
else if (iBurstTime == TIME_SLICE)
oTemp->iState = READY;
}
/*
* Simulates the job running on a CPU for a number of milli seconds
*/
void runProcess(int iBurstTime, struct timeval * oStartTime, struct timeval * oEndTime)
{
struct timeval oCurrent;
long int iDifference = 0;
gettimeofday(oStartTime, NULL);
do
{
gettimeofday(&oCurrent, NULL);
iDifference = getDifferenceInMilliSeconds((*oStartTime), oCurrent);
} while(iDifference < iBurstTime);
gettimeofday(oEndTime, NULL);
}