具体内容
采用的调度算法:高优先数调度算法和先来先服务算法
进程由进程控制块PCB表示,PCB中包括a)进程名b)优先数c)进程到达时间d)进程结束时间e)进程状态f)已占用CPU时间(进程运行一个时间片后加一)
运行一个时间片后进程优先级降一级
利用文件操作模拟进程的操作
概念图
实现过程
导入的库和宏定义
#include#include #include #include #include #include #define u8 char #define u32 unsigned int #define MAXLINE 1024 //工作队列和等待队列长度 #define MAXNUM 100 #define WAIT 0 //进程状态为WAIT #define RUN 1 //进程状态为RUN #define FINISH 2 //进程状态为FINISH #define NEWBUF 1 //此时工作队列为新队列 #define BUF 0 //此时工作队列为默认队列 #define THENULL 0 //表示进程块此时为NULL #define THETRUE 1 //表示进程块此时有进程 char* VALUE = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz�";
建立进程块PCB结构体
struct PCB{ FILE* open_file; u8 * file_name; clock_t arrive_time; //到达时间 clock_t level_time; //结束时间 int prior_number; //优先级 u8 program_status; //程序状态 u8 detection_null_or_value; //判断此时进程块是否为空 u8 occupy_time_slice_times; //已占用的CPU时间 int data_write_number; //记录已经向文件中写入内容的长度 }; #define PCB_T struct PCB*
建立工作队列结构体
struct program_queue{ struct PCB pcb_buf[MAXLINE]; //默认队列,一开始将进程块存入这里 struct PCB pcb_new_buf[MAXLINE];//与默认队列交替管理进程块 u32 queue_line; //工作队列的长度 u8 buf_state; //判断此时正在使用的是哪一个队列 }; #define program_queue_t struct program_queue*
建立CPU时间片结构体
struct cpu_time_slice{ clock_t start_time; //时间片开始执行时间 clock_t end_time; //时间片结束执行时间 u32 time_slice_bulk; //每个时间片的时间,单位ms }; #define cpu_time_slice_t struct cpu_time_slice*
清空new队列方法
void bzero_queue_new(program_queue_t queue_t) { for(int i = 0 ; i < MAXLINE ; i++) { queue_t -> pcb_new_buf[i].detection_null_or_value = THENULL;//detection_null_or_value等于THENULL表示这个结构体为空 } }
清空默认队列方法
void bzero_queue(program_queue_t queue_t) { for(int i = 0 ; i < MAXLINE ; i++) { queue_t -> pcb_buf[i].detection_null_or_value = THENULL; } }
初始化时间片机构体方法
void init_time_slice(cpu_time_slice_t time_slice) { time_slice -> time_slice_bulk = 20;//设置一个时间片时间为20ms }
初始化工作队列方法
void init_program_queue(program_queue_t queue) { bzero_queue(queue); bzero_queue_new(queue); queue -> queue_line = 0; queue -> buf_state = BUF;//设置此时工作队列默认使用的pcb_buf }
工作队列排序方法(按照进程优先级排序)
void queue_sort(program_queue_t queue_t) { int len = queue_t -> queue_line;//获取工作队列长度 if(len == 0) return; if(queue_t -> buf_state == BUF)//判断当前使用哪个数组作为工作队列 { bzero_queue_new(queue_t); struct PCB tm; tm.program_status = -1; PCB_T tmp_pcb = &tm; for(int i = 0 ; i < queue_t -> queue_line ; i++)//开始排序 { for(int j = 0; j < queue_t -> queue_line ; ++j) { if(queue_t -> pcb_buf[j].detection_null_or_value == THENULL) continue; if(j <= 0) tmp_pcb = &(queue_t -> pcb_buf[j]); else if(-1 == tmp_pcb -> program_status) tmp_pcb = &(queue_t -> pcb_buf[j]); else { if(tmp_pcb -> prior_number > queue_t -> pcb_buf[j].prior_number) { tmp_pcb = &(queue_t -> pcb_buf[j]); } } } queue_t -> pcb_new_buf[i] = *tmp_pcb; tmp_pcb -> detection_null_or_value = THENULL; } queue_t -> buf_state = NEWBUF;//由另一个数组接收排序结果,排序完全结束后切换列表目前使用的数组 } else { bzero_queue(queue_t); struct PCB tm; tm.program_status = -1; PCB_T tmp_pcb = &tm; for(int i = 0 ; i < queue_t -> queue_line ; i++) { for(int j = 0; j < queue_t -> queue_line ; ++j) { if(queue_t -> pcb_new_buf[j].detection_null_or_value == THENULL) continue; if(j <= 0) tmp_pcb = &(queue_t -> pcb_new_buf[j]); else if(-1 == tmp_pcb -> program_status) tmp_pcb = &(queue_t -> pcb_new_buf[j]); else { if(tmp_pcb -> prior_number > queue_t -> pcb_new_buf[j].prior_number) { tmp_pcb = &(queue_t -> pcb_new_buf[j]); } } } queue_t -> pcb_buf[i] = *tmp_pcb; tmp_pcb -> detection_null_or_value = THENULL; } queue_t -> buf_state = BUF; } }
初始化进程块PCB
void init_pcb_object(PCB_T pcb_t,char** argv,int i) { pcb_t -> open_file = NULL; if(NULL == (pcb_t -> open_file = fopen(argv[i],"a"))) { perror("open file error"); exit(0); } pcb_t -> file_name = argv[i]; pcb_t -> prior_number = rand() % 8; //进程优先级由随机数分配 pcb_t -> arrive_time = clock(); //获取进程进入时间 pcb_t -> program_status = WAIT; //设置进程状态为等待 pcb_t -> detection_null_or_value = THETRUE; //设置次进程块非空 pcb_t -> occupy_time_slice_times = 0;//初始化使用CPU时间为0 pcb_t -> data_write_number = 0; //文件写入内容长度初始化为0 }
主函数
int main(int argc,char **argv) { if(argc <= 1) { perror("parameter <= 1"); exit(1); } struct program_queue _queue; //创建工作队列对象 init_program_queue(&_queue); struct cpu_time_slice cts; //创建CPU时间片对象 init_time_slice(&cts); int program_numer = argc - 1; //设置目前的进程数为argc - 1,该变量用于通过下标访问进程需要-1 for(int i = 1 ; i < argc ; i++) { init_pcb_object(&(_queue.pcb_buf[i - 1]),argv,i); _queue.queue_line++; }//循环初始化进程块 printf("program queue: "); for(int i = 1 ; i < argc ; i++) { printf("[ %s ] , ",_queue.pcb_buf[i - 1].file_name); }//打印进程名称 printf(" "); queue_sort(&_queue);//将进程队列进行排序 printf("program queue sort end... "); while(1)//准备执行进程 { if(0 >= program_numer) break; for(int i = 0 ; i < _queue.queue_line ; i++) { if(_queue.buf_state == BUF) { if(THENULL == _queue.pcb_buf[i].detection_null_or_value) continue; printf("wait queue:"); for(int k = 0 ; k < _queue.queue_line ; k++) { if(THENULL == _queue.pcb_buf[k].detection_null_or_value) continue;//如果该进程块为空就跳过 printf("[ %s ]",_queue.pcb_buf[k].file_name); }//打印等待执行的进程名称 printf(" program start operation... "); printf("operation program name: %s ",(_queue.pcb_buf[i].file_name));//打印将要执行的进程名称 _queue.pcb_buf[i].program_status = RUN;//更改进程块状态 } else { if(THENULL == _queue.pcb_new_buf[i].detection_null_or_value) continue; printf("wait queue:"); for(int k = 0 ; k < _queue.queue_line ; k++) { if(THENULL == _queue.pcb_new_buf[k].detection_null_or_value) continue; printf("[ %s ]",_queue.pcb_new_buf[k].file_name); } printf(" program start operation... "); printf("operation program name: %s ",(_queue.pcb_new_buf[i].file_name)); _queue.pcb_new_buf[i].program_status = RUN; } cts.start_time = clock();//获取开始时间 while(1)//进程开始执行 { cts.end_time = clock();//获取结束时间 if(cts.end_time - cts.start_time >= cts.time_slice_bulk)//结束时间 - 开始时间 = 预设的时间片长度则进程终止执行 { if(_queue.buf_state == BUF) { _queue.pcb_buf[i].program_status = WAIT; _queue.pcb_buf[i].prior_number++;//进程使用CPU时间+1 _queue.pcb_buf[i].occupy_time_slice_times++; _queue.pcb_new_buf[i] = _queue.pcb_buf[i];//将进程放到另一个队列等待 _queue.pcb_buf[i].detection_null_or_value = THENULL;//将当前队列的此进程块设为空 } else { _queue.pcb_new_buf[i].program_status = WAIT; _queue.pcb_new_buf[i].prior_number++; _queue.pcb_new_buf[i].occupy_time_slice_times++; _queue.pcb_buf[i] = _queue.pcb_new_buf[i]; _queue.pcb_new_buf[i].detection_null_or_value = THENULL; } break; } if(_queue.buf_state == BUF) { if(VALUE[_queue.pcb_buf[i].data_write_number] == '�')//判断进程是否已经完成任务 { _queue.pcb_buf[i].level_time = clock();//获取结束时间 printf("program [ %s ] execute end... program run time: %d ms ",_queue.pcb_buf[i].file_name,_queue.pcb_buf[i].level_time - _queue.pcb_buf[i].arrive_time);//进程的结束时间减去进程的进入时间计算出进程运行耗时 _queue.pcb_buf[i].detection_null_or_value = THENULL; fclose(_queue.pcb_buf[i].open_file);//关闭文件 program_numer--;//进程数-1 break; } if(-1 == fputc(VALUE[_queue.pcb_new_buf[i].data_write_number],_queue.pcb_new_buf[i].open_file))//向文件中写入数据 { perror("write error "); perror(strerror()); for(int i = 0 ; _queue.queue_line ; i++) { fclose(_queue.pcb_buf[i].open_file); } //exit(1); } else { _queue.pcb_buf[i].data_write_number++;//写入内容的长度+1 } } else { if(VALUE[_queue.pcb_new_buf[i].data_write_number] == '�') { _queue.pcb_new_buf[i].level_time = clock(); printf("program [ %s ] execute end... program run time: %d ms ",_queue.pcb_new_buf[i].file_name,_queue.pcb_new_buf[i].level_time - _queue.pcb_new_buf[i].arrive_time); _queue.pcb_new_buf[i].detection_null_or_value = THENULL; fclose(_queue.pcb_new_buf[i].open_file); program_numer--; break; } if(-1 == fputc(VALUE[_queue.pcb_new_buf[i].data_write_number],_queue.pcb_new_buf[i].open_file)) { perror("write error "); perror(strerror()); for(int i = 0 ; _queue.queue_line ; i++) { fclose(_queue.pcb_new_buf[i].open_file); } //exit(1); } else { _queue.pcb_new_buf[i].data_write_number++; } } } } if(_queue.buf_state == BUF)//更换当前队列 { _queue.buf_state = NEWBUF; queue_sort(&_queue);//重新按照优先级排序队列 } else { _queue.buf_state = BUF; queue_sort(&_queue); } } return 0 ; }
审核编辑:汤梓红
评论
查看更多