一、调度程序概念
本文介绍服务成的周期性调度,即让程序按照周期运行。如果是常驻内存的服务程序,当该服务程序正常/异常终止后,在一个周期后再次启动。保证了服务程序的周期运行。
二、用到的一些知识
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;
}