多线程+链表模拟RR调度算法

在这里插入图片描述
程序还有点小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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清欢_小铭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值