利用C语言模拟程序调度机制

嵌入式技术

1372人已加入

描述

具体内容

采用的调度算法:高优先数调度算法和先来先服务算法

进程由进程控制块PCB表示,PCB中包括a)进程名b)优先数c)进程到达时间d)进程结束时间e)进程状态f)已占用CPU时间(进程运行一个时间片后加一)

运行一个时间片后进程优先级降一级

利用文件操作模拟进程的操作

概念图pcb

实现过程

导入的库和宏定义

 

#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 ;
}

 

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分