发生如图错误,已知到错误原因,求解决方案
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
using namespace std;
#define MAXSIZE 5
#define INF 100
typedef struct servedtime1 {
int front;
int rear;
double data[MAXSIZE];
} servedtime1;
servedtime1* initservedtime1() {
servedtime1* X = (servedtime1*)malloc(sizeof(servedtime1));
X->front = X->rear = 0;
return 0;
}//初始化队列
servedtime1* X;
int isFull(servedtime1* X) {
if ((X->rear + 1) % MAXSIZE == X->front) {
return 1;
}
else {
return 0;
}
}//判断队列是否满
int isEmpty(servedtime1* X) {
if (X->front == X->rear) {
return 1;
}
else {
return 0;
}
}//判断队列是否为空
int enservedtime1(servedtime1* X, double data) {
if (isFull(X)) {
return 0;
}
else
{
X->data[X->rear] = data;
X->rear = (X->rear + 1) % MAXSIZE;
return 1;
}
}//入列
double deservedtime1(servedtime1* X) {
if (isEmpty(X)) {
return -1;
}
else {
double data = X->data[X->front];
X->front = (X->front + 1) % MAXSIZE;
return data;
}
}//出列
typedef struct Job {
char name;
double arrive;
double serve;
double start;
double finish;
struct Job* next;
}JobSL;
typedef struct S {
int value;
JobSL* waitingjobs;
};
S mutex;
void init()
{
mutex.value = 0;
mutex.waitingjobs = (JobSL*)malloc(sizeof(Job));
mutex.waitingjobs->next = NULL;
};
//为了测试输出队列
void print(JobSL* head)
{
JobSL* p = head->next;
cout << "当前队列:";
while (p != NULL)
{
cout << p->name;
p = p->next;
}
cout << endl;
}
//插入函数
void Insert(JobSL* head, double stime, char name)
{
JobSL* p, * q, * r;
p = head->next;//p为首元素 p用来遍历无序部分的元素
q = head; //p为头节点
while (p != NULL) {
//if (p->price == price) {//已存在就增加数量
// p->count += count;
// return;
//}
if (p->serve >= stime) {//找到合适的插入位置
r = (JobSL*)malloc(sizeof(struct Job));
r->serve = stime;
r->name = name;
r->next = q->next;//把r插入到
q->next = r; //q的后面
cout << "当前任务入队完成" << endl;
print(head);
return;
}
else if (p->serve < stime) {
q = p;//q始终指向p的前驱
p = p->next;
}
}
//走到这里说明,表中没有比要插入的price还要大的结点
//直接接在链表表尾就行
r = (JobSL*)malloc(sizeof(struct Job));
r->serve = stime;
r->name = name;
r->next = NULL;
q->next = r;
cout << "当前任务入队完成" << endl;
print(head);
return;
}
void Insert2(JobSL* head, double stime, char name)
{
JobSL* p, * q, * r;
p = head->next;//p为首元素 p用来遍历无序部分的元素
q = head; //p为头节点
while (p != NULL) {
q = p;//q始终指向p的前驱
p = p->next;
}
//走到这里说明,表中没有比要插入的price还要大的结点
//直接接在链表表尾就行
r = (JobSL*)malloc(sizeof(struct Job));
r->serve = stime;
r->name = name;
r->next = NULL;
q->next = r;
cout << "当前任务入队完成" << endl;
print(head);
return;
}
//因为处理机一次只能处理一个任务,即需要一个互斥信号量mutex(value=0)(原理参考P53-55)
//数据结构为改进后的记录型信号量(原始记录型信号量可以直接用于先进先出,但是短优先不行,需要改进)
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
void wait(JobSL* applier) { //applier表示申请的这个新作业,有新作业后台队列就需要重新排序
if (mutex.value < 0 && applier != NULL) { //-----------旧任务未结束,新任务到达,当前cpu正在被使用,
cout << "CPU被占用" << endl;
Insert(mutex.waitingjobs, applier->serve, applier->name); //申请任务的服务时间和名字写道队列里
}
else if (mutex.value < 0 && applier == NULL) { //---------旧任务正在执行
//block(S->list)
cout << "阻塞等待队列" << endl;
}
else { //---------------------旧任务已结束,没有新任务到达 ,当前cpu空闲
mutex.value--;//此处如果不是全局变量跳出这个函数之后s的value就又回到0了
cout << "当前任务申请到了资源" << endl;
//tempjob=applier; //可能有空队列,需要在后面判断
}
}
servedtime1* sort(servedtime1* X) {
if ((X->rear - X->front + MAXSIZE) % MAXSIZE != 0) {
servedtime1* X = initservedtime1();
int N;
N = (X->rear - X->front + MAXSIZE) % MAXSIZE;
double buffer;
double min;
for (int i = 0; i < N; i++) {
min = INF;
for (int j = i; j < N; j++) {
buffer = deservedtime1(X);
if (buffer < min) {
if (min != INF) enservedtime1(X, min);
min = buffer;
}
else {
enservedtime1(X, buffer);
}
}
enservedtime1(X, min);
}
}
return X;
//else {
// enservedtime1(X, 1);
//}
}
void wait2(double applierserv) {
//队列有元素
enservedtime1(X, applierserv);
X = sort(X);
//队列无元素
enservedtime1(X, applierserv);
}
JobSL* signal() {
mutex.value++;
if (mutex.value == 0) {
//-----------------------当前时间等待队列空?-----------------------------------------//
if (mutex.waitingjobs->next == NULL) {
cout << "此时等待队列空" << endl;
return NULL;
}
else {
cout << "唤醒等待队列" << endl;
print(mutex.waitingjobs);
//取出这个元素后就删除这个元素被删除节点是第一个节点:只需使head指向第二个节点即可
JobSL* formeset = mutex.waitingjobs->next;//(一开始是头指针)指针后移,取出队头
//mutex.waitingjobs->next = formeset->next;
//free(formeset);//这里不能释放空间,释放了就找不到了
return formeset;
}
}
}
JobSL* getend(JobSL* head)
{
JobSL* p = head->next;
while (p->next == NULL) {
p = p->next;
return p;
}
}//获取尾节点
int circle(JobSL* head) {
JobSL* temNode;
JobSL* endNode;
endNode = getend(head);
temNode = head->next;
endNode->next = temNode;
head->next = temNode->next;
temNode->next = NULL;
return 1;
}
void con() {
wait(NULL);
}
double servedtime = 0;
int finishedjob = 0;
JobSL* tempjob = (JobSL*)malloc(sizeof(struct Job));
void Sjf(double clock, Job allj[], int n) {
double timespice = 0.5;
double servedtime = 0;
//------------------------------------------先判断当前时间是到达时间吗---------------------------------//
int i = 0;
for (; i < n; i++) {
if (allj[i].arrive == clock) {
JobSL* applier = (JobSL*)malloc(sizeof(struct Job));/*2.结构体指针需要初始化*/
applier->name = allj[i].name;
applier->arrive = allj[i].arrive;
applier->serve = allj[i].serve;
if (mutex.value == 0) {//表示此时没有任务(第一次申请时可能cpu被征用也可能空闲)
tempjob = applier;
}
cout << allj[i].name << "任务已到达\t";
wait(applier);//如果上一个任务刚结束,下一个任务就到达,这里还申请不到资源,入队
wait2(allj[i].serve);
break;
}
}
//-----------------------------------当前时间有正在处理的任务吗?------------------------------------//
//-----------------------------------当前任务结束了吗?-------------------------------------------//
servedtime = deservedtime1(X);
servedtime = servedtime + timespice;
double remainserv = tempjob->serve - servedtime;
cout << "作业" << tempjob->name << "未结束\t";
cout << "作业" << tempjob->name << "已处理了" << servedtime << endl;
if (servedtime >= tempjob->serve) {
//----------------------------------当前时间旧任务结束的瞬间?--------------------------------------------------------------------//
if (mutex.value == -1) { //当前任务结束。先把CPU释放了 ,为了防止当前任务结束后一段时间没有新任务导致多次释放
cout << "作业" << tempjob->name << "已结束\t";
JobSL* nextjob = signal(); //Ⅱ这里的释放资源是当前任务执行结束后的释放,是最后一次释放,此次释放完毕当前任务应该删除
JobSL* formeset = mutex.waitingjobs->next; //删除当前已执行完的任务(此处实际上formeset和nextjob是一个东西)
mutex.waitingjobs->next = formeset->next;
finishedjob++; //已经处理完的任务加一
cout << "--------当前时刻已结束执行任务数:" << finishedjob << endl;
if (nextjob != NULL) { //出队的任务作为下一步要执行的任务
tempjob = nextjob;//指针可以直接赋值不用一个一个的赋值属性
cout << "作业" << tempjob->name << "已出队" << endl;
print(mutex.waitingjobs);
con();
}
else {
cout << "当前时刻上一任务刚处理完,且队列为空,正在等待新任务到达……" << endl;
}
}
else {//mutex.value==0
cout << "当前时刻,后备队列为空,且无新任务到达,cpu空闲" << endl;
}
return; //这种情况是任务结束从而切换到下一个任务的情况,而不是时间片结束才切换到下一个任务的情况(下面的代码),所以直接返回
}
if (mutex.waitingjobs->next != NULL) { //至少队列里要有一个元素才有释放cpu的必要(队列里没有元素,实际上执行一个时间片之后也要释放,但释放后又被自己占用了)
JobSL* nextjob = signal(); //Ⅰ每执行完一个时间片都要释放cpu,这个程序在任务出队列的时候没有删除
Insert(mutex.waitingjobs, tempjob->serve, tempjob->name);//当前这个时间片的任务处理完入队
tempjob = nextjob; //当前时间片结束,切换到下一个任务
}
enservedtime1(X, servedtime);//sfj按大小入队
//if (mutex.waitingjobs->next!=NULL || mutex.waitingjobs->next->next != NULL) { //等待队列里至少要有两个元素才能执行交换
// //circle(mutex.waitingjobs); //任务等待队列做的相应操作
//}
}
void input(int n, Job j[])
{
for (int i = 0; i < n; i++) {
cout << "请顺次输入①任务名称,②到达时间,③服务时间: ";
cin >> j[i].name >> j[i].arrive >> j[i].serve;
}
cout << endl;
}
int main()
{
init();
servedtime1* X = initservedtime1();//初始化队列
int n;
cout << "请输入任务数量: ";
cin >> n;
Job j[100];
input(n, j);
//因为调度跟时间有关,先加一个计数器,假设这个方法返回一个整形t
for (double clock = 0; clock <= 100; clock++)
{
cout << "现在时刻" << clock << "---------------------------" << endl;
Sjf(clock, j, n);
if (finishedjob == n)//加上当前这个已经完成了n个任务
{
cout << "所有任务均已处理完成--------------------------END";
break;
}
}
return 0;
}