山东大学2018级操作系统实验三

题目描述

设有两个并发执行的父子进程,不断循环输出各自进程号、优先数和调度策略。进程初始调度策略均为系统默认策略和默认优先级。当某个进程收到 SIGINT 信号时会自动将其优先数加1,收到 SIGTSTP 信号时会自动将其优先数减 1。请编程实现以上功能。

实验思路

为父、子进程都注册优先级加一、减一的信号。响应信号改变优先级。
注意减优先级的操作必须在root用户下才有权限。

实验涉及的知识点

1、在linux系统中调度策略(policy)可以是以下3种:
a.SCHED_OTHER默认的分时调度策略(值等于0)
b.SCHED_FIFO先进先先出调度策略(值等于1)
c.SCHED_RR时间片轮转调度策略(值等于2)
后两种专用于对响应时间有特殊要求的进程,并且会抢先于SCHED_OTHER调度策略的进程而执行。一个具有SCHED_FIFO调度策略的进程只能被更高优先级的进程抢先,但具有SCHED_RR调度策略的进程必要时可以与同级进程共享时间片。
2、进程优先数(prio)由静态优先数和动态优先数两部分组成,值越小调度优先级越高。具有SCHED_OTHER策略的进程静态优先数总是0。动态优先数与进程的执行状态有关,但可以使用nice命令或系统调用加大进程优先数使其优先级降低,或用系统调用setpriority分别按进程或进程组或用户号设置介于-20到+20之间的动态优先数。
3、与进程调度策略有关的系统调用函数原型都声明在以下文件中:
#include <sched.h>
#include <sys/time.h>
#include <sys/resource.h>
4、设置进程调度策略的系统调用语法为:
int sched_setscheduler(pid_t pid,int policy,const struct sched_param *sp);
pid 进程号
policy以上说明的3种调度策略之一
sp调度参数结构指针,调度参数结构主要存有调度优先数
struct sched_param {

int sched_priority;

};
返回值: 执行成功后返回0
5、获取进程调度策略的系统调用语法为:
int sched_getscheduler(pid_t pid);
pid 进程号
返回值: 进程当前的调度策略
6、获取进程动态优先数的系统调用语法为:
int getpriority(int which,int who);
which设置的对象。可以是:
进程PRIO_PROCESS
进程组PRIO_PGRP
用户PRIO_USER
who对应设置对象的进程号或组号或用户号
返回值: 所有匹配进程中的最高优先数
7、设置进程动态优先数的系统调用语法为:
int setpriority(int which,int who,int prio);
which设置的对象。可以是:
进程PRIO_PROCESS
进程组PRIO_PGRP
用户PRIO_USER
who对应设置对象的进程号或组号或用户号
prio要设置的进程优先数
返回值: 所有匹配进程中的最高优先数

源代码

#include <sched.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// SIGINT  程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
// SIGTSTP  停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl-Z)发出这个信号
typedef void (*sighandler_t)(int);
void sigcat_1()
{
    printf("SIGINT信号,优先度加一\n");
    setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid()) + 1);
}
void sigcat_2()
{
    printf("SIGTSTP信号,优先度减一\n");
    setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid()) - 1);
}
int main(int argc, char *argv[])
{
    int i, j;
    pid_t pid;
    printf("Ctrl-C让进程优先度加一,Ctrl-Z让进程优先度减一\n");
    pid = fork();
    if (pid < 0)
    {
        fprintf(stderr, "fork failed");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)
    {
        signal(SIGINT, (sighandler_t)sigcat_1);
        signal(SIGTSTP, (sighandler_t)sigcat_2);
        for (i = 0; i < 20; i++)
        {
            printf("子进程 PID = %d 优先级= %d ,调度策略= %d\n", getpid(), getpriority(PRIO_PROCESS, 0), sched_getscheduler(getpid()));
            sleep(1);
        }
    }
    else
    {
        signal(SIGINT, (sighandler_t)sigcat_1);
        signal(SIGTSTP, (sighandler_t)sigcat_2);
        for (i = 0; i < 20; i++)
        {
            printf("父进程 PID = %d 优先级= %d ,调度策略= %d\n", getpid(), getpriority(PRIO_PROCESS, 0), sched_getscheduler(getpid()));
            sleep(1);
        }
    }
}
    }
  }
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值