タイム スライス ローテーション アルゴリズムの実装 (シミュレーション) コンピューター オペレーティング システムの実験 5: プロセス スケジューリング アルゴリズムのシミュレーション - RR

実験内容:
タイムスライス回転アルゴリズムを実現する (シミュレーション)、要件は次のとおりです:
1. 使用するデータ構造
/* PCB /
struct PCB
{ pid_t pid;// プロセス PID int state; // ステータス情報、1 は実行中を意味します、0は一時停止を意味し、-1は終了を意味しますunsigned long run_time;//経過した実行時間unsigned long need_running_time;//残りの実行時間}; /





PCB set*/
struct PCB pcb[TOTAL]; // PCB set
2. アルゴリズムのアイデアとアルゴリズム
実装 メイン関数(main)とディスパッチ関数(Dispatch)。
(1) メイン関数 (main) の中核となる関数は、
6 つのサブプロセスの作成とサブプロセス PCB の初期化を実現することです。サブプロセス PCB を初期化すると、ステータスは 0 に設定され、実行
時間は乱数によって生成されます。子プロセスは作成後、SIGSTOP信号によりサスペンド状態となり、
ディスパッチ関数(Dispatch)で選択されて初めて実行を継続し、子プロセスxが実行中であるという情報を出力します。同時に、メイン プログラムにタイマーを設定する必要があります。タイマーの間隔はタイム スライスの長さです。タイム スライスが終了すると、ディスパッチ関数 (Dispatch)
が呼び出され、プログラムが再選択されます。 。(2) ディスパッチ機能のコア機能:


実行中の子プロセスを一時停止し、ステータスを 0 に変更し、実行経過時間と残り実行時間を変更します。
サブプロセスの残り時間が 0 以下の場合、実行が完了し、PCB ステータスが -1 に変更され、サブプロセスが終了したことを意味します。
次のサブプロセスを再選択すると、状態は 1 になり、サブプロセスの実行経過時間と残り実行時間を出力し、サブプロセスの実行を再開します

すべての子プロセスが終了すると、親プログラムも終了します。

コードは以下のように表示されます:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

//宏定义
#define TOTAL 6 //子进程总数
#define UNIT_TIME 200 //时间片长度(单位:毫秒)
#define UNIT_TICKS (UNIT_TIME * 1000) //计算时间片的ticks数

//进程状态
#define STATE_RUNNING 1
#define STATE_WAITING 0
#define STATE_FINISHED -1
void Dispatch(int signum);
/* PCB */
struct PCB          
{
    
    
        pid_t pid;//进程PID
        int state; //状态信息,1表示正在运行,0表示暂停,-1表示结束
        unsigned long runned_time;//已运行时间
        unsigned long need_running_time;//剩余运行时间
};

/* PCB集合 */
struct PCB pcb[TOTAL];  //PCB集合

//主函数
int main(int argc, char *argv[])
{
    
    
        //定义变量
        int i, j;

        //初始化随机数种子
        srand((unsigned int)time(NULL));

        //初始化PCB集合
        for (i = 0; i < TOTAL; i++)
        {
    
    
                pcb[i].state = STATE_WAITING;
                pcb[i].runned_time = 0;
                pcb[i].need_running_time = rand() % 1000; //随机产生运行时间
        }

        //创建子进程
        for (i = 0; i < TOTAL; i++)
        {
    
    
                if ((pcb[i].pid = fork()) == 0)
                {
    
    
                        //子进程执行代码
                        while (1)
                        {
    
    
                                //处于暂停状态,等待信号
                                kill(getpid(), SIGSTOP);

                                //子进程结束
                                if (pcb[i].need_running_time == 0)
                                {
    
    
                                        exit(0);
                                }
                                //打印子进程信息
                                printf("\n");
                                printf("子进程ID:%d\n", pcb[i].pid);
		printf("已运行时间:%ld\n", pcb[i].runned_time);
		printf("剩余运行时间:%ld\n", pcb[i].need_running_time);
		                            //模拟运行
                            usleep(UNIT_TICKS);
                            pcb[i].runned_time++;
                            pcb[i].need_running_time--;
                    }
            }
    }

    //设置定时器
    struct itimerval itv;
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = UNIT_TICKS;
    itv.it_value.tv_sec = 0;
    itv.it_value.tv_usec = UNIT_TICKS;
    setitimer(ITIMER_REAL, &itv, NULL);

    //捕捉SIGALRM信号
    signal(SIGALRM, Dispatch);

    //等待子进程结束
    for (i = 0; i < TOTAL; i++)
    {
    
    
            waitpid(pcb[i].pid, NULL, 0);
    }

    //程序结束
    printf("\n程序执行结束!\n");
    return 0;
}
//分派函数
void Dispatch(int signum)
{
    
    
//暂停正在执行的进程
int i;
for (i = 0; i < TOTAL; i++)
{
    
    
if (pcb[i].state == STATE_RUNNING)
{
    
    
kill(pcb[i].pid, SIGSTOP);
break;
}
}
    //检查所有进程是否结束
    int finished = 1;
    for (i = 0; i < TOTAL; i++)
    {
    
    
            //如果剩余运行时间小于零,则说明该进程结束
            if (pcb[i].need_running_time < 0)
            {
    
    
                    pcb[i].state = STATE_FINISHED;
            }
            else if (pcb[i].state != STATE_FINISHED)
            {
    
    
                    finished = 0;
            }
    }

    //如果所有进程都结束,则停止定时器,结束程序
    if (finished)
    {
    
    
            struct itimerval itv;
            itv.it_interval.tv_sec = 0;
            itv.it_interval.tv_usec = 0;
            itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
return;
}
    //选择下一个要执行的进程
    for (i = 0; i < TOTAL; i++)
    {
    
    
            //找到第一个状态为0的进程
            if (pcb[i].state == STATE_WAITING)
            {
    
    
                    pcb[i].state = STATE_RUNNING;
                    kill(pcb[i].pid, SIGCONT);
                    break;
            }
    }

}

上記のコードの実行結果は次のとおりです。
RR実験結果
子プロセス ID が常に 0 であることがわかります (ここに問題があります。読者は修正してください。修正方法がある場合は、コメント エリアにコメントしてください) )、子プロセスは 6 つだけ作成されます。
もっと良い方法があれば、またシェアさせていただきます。

おすすめ

転載: blog.csdn.net/weixin_52357218/article/details/128274162