调度程序的实现

一、调度程序概念

本文介绍服务成的周期性调度,即让程序按照周期运行。如果是常驻内存的服务程序,当该服务程序正常/异常终止后,在一个周期后再次启动。保证了服务程序的周期运行。

二、用到的一些知识

int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);

注意:
1)如果执行程序失败则直接返回-1,失败原因存于errno中。
2)新进程的进程编号与原进程相同,但是,新进程取代了原进程的代码段、数据段和堆栈。
3)如果执行成功则函数不会返回,当在主程序中成功调用exec后,被调用的程序将取代调用者程序,也就是说,exec函数之后的代码都不会被执行。
4)在实际开发中,最常用的是execl()和execv(),其它的极少使用。

示例:

//使用
#include <iostream>
#include <string.h>
#include <unistd.h>
using namespace std;

int main(int argc,char *argv[])
{
  int ret=execl("/bin/ls","/bin/ls","-lt","/tmp",0);  // 最后一个参数0不能省略。
  cout << "ret=" << ret << endl;
  perror("execl");

  /*
  char *args[10];
  args[0]="/bin/ls";
  args[1]="-lt";
  args[2]="/tmp";
  args[3]=0;     // 这行代码不能省略。

  int ret=execv("/bin/ls",args);
  cout << "ret=" << ret << endl;
  perror("execv");
  */
}

三、调度程序的实现

/*
 *  procctl.cpp  本程序用于周期性的调度程序,为调度模块。
 *  作者:张咸武。
*/
// 本程序不需要包含_public.h,没必要依赖那么多头文件。
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<iostream>

int main(int argc,char* argv[])
{
    if(argc<3)
    {
        std::cout<<"程序参数太少"<<std::endl;
        std::cout<<"Example:/home/xianwu/mytest/MSofService/procctl 10 /home/xianwu/mytest/MSofService/show 5 woshishuaibi"<<std::endl;

    }

    for(int ii=0;ii<64;ii++)
    {
        signal(ii,SIG_IGN);
        //close(ii);
    }

    // 生成子进程,父进程退出,让程序运行在后台,由系统1号进程托管,不受shell的控制。
    if(fork()!=0) exit(0);

    //恢复为默认行为(启用了子进程退出的信号),让父进程可以调用wait()函数等待子进程退出。
    signal(SIGCHLD,SIG_DFL);

    char* pargv[argc-2];
    for(int ii=2;ii<argc;ii++)
        pargv[ii-2] = argv[ii];
    pargv[argc-2]=nullptr;      //指针数组最后赋nullptr表示结束。

    while(true)
    {
        if(fork()==0)   //子进程运行程序
        {
            execv(argv[2],pargv);
            exit(0);
        }
        else
        {
            // wait()函数会阻塞,直到被调度的程序终止。
            wait(nullptr);        // 如果不在乎子进程的终止状态(正常或异常)。
            sleep(atoi(argv[1]));    // 休眠timetvl秒,然后回到循环。
        }
    }

    return 0;
}
  • 不处理退出信号,调度程序很重要,为了防止调度程序被误杀。

  • 在procctl.cpp中如果关闭了I/O,将影响被调度的程序(也会关闭I/O)。这样做是合理的,服务程序我们是单独编写,可能有些IO用于调试,这样的话直接屏蔽了。

  • signal(SIGCHLD,SIG_DFL); //恢复为默认行为(启用了子进程退出的信号),让父进程可以调用wait()函数等待子进程退出。

给出show程序的例子:

#include<iostream>
#include <unistd.h>

int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        std::cout<<"程序参数不匹配"<<std::endl;
        std::cout<<"Example:/home/xianwu/mytest/MSofService/show 5 woshishuaibi"<<std::endl;

    }

    for(int ii=0;ii<atoi(argv[1]);ii++)
    {
        std::cout<<argv[2]<<std::endl;
        sleep(1);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值