素材来源:网络素材
整理:技术让梦想更伟大 | 李肖遥
概念图
#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\0";
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*
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*
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;
}
}
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("\n");
queue_sort(&_queue);//将进程队列进行排序
printf("program queue sort end...\n");
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("\nprogram start operation...\n");
printf("operation program name: %s\n",(_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("\nprogram start operation...\n");
printf("operation program name: %s\n",(_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] == '\0')//判断进程是否已经完成任务
{
_queue.pcb_buf[i].level_time = clock();//获取结束时间
printf("program [ %s ] execute end... program run time: %d ms\n",_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\n");
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] == '\0')
{
_queue.pcb_new_buf[i].level_time = clock();
printf("program [ %s ] execute end... program run time: %d ms\n",_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\n");
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 ;
}
版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。