创建守护进程

自己敲的创建守护进程,详细过程在注释里。。。自己总结的笔记吧。。。
注意编号0—7,算是大概步骤,守护进程就算结束了
8是检测。。。方法是将一个字符串不断地追加在一个文件里,如果成功就可以通过看到文件越来越长。。。

 #include< stdio.h>
 #include< string.h>
 #include< stdlib.h>
 #include< sys/types.h>
 #include< fcntl.h>
 #include< unistd.h>
 #include< signal.h>        //sigal
 #include< sys/stat.h>
 #include< syslog.h>
 #include< sys/param.h>   //包含NOFILE
 #include < sys/wait.h >

int main()
{
    //0.屏蔽一些有关控制终端操作的信号。这是为了防止在守护进程没有正常运转起来时,控制终端受到干扰退出或挂起。
    signal(SIGTTOU,SIG_IGN);
    signal(SIGTTIN,SIG_IGN);
    signal(SIGTSTP,SIG_IGN);
    signal(SIGHUP ,SIG_IGN);
    pid_t pid;
    int i;
    pid=fork();//1,产生一个子进程,让父进程退出
    /*
    创建一个进程后,
        父进程没有等待(调用wait / waitpid)子,
            如果子结束了,那子就会变成僵尸进程
    (僵尸进程虽然释放了内存,但是保留有一定的信息
    (包括进程号,退出状态,退出时间等,)
    其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程.。)
        但如果父进程等待了,父进程就会变为停止状态,影响进程并发性;
        所以就会两难,解决办法在下面(处理SIGCHLD信号,通知内核,父不接收对子进程的结束信号)
            但如果父进程提前结束那么子进程就会变成孤儿进程,他会被init进程收养,(这里有个坑,在命令行下是init,但是在图形界面模式是upstart(upstart是Ubuntu使用的用来代替init的东西,它的优点在于更快的启动系统,以及在硬件热拔插的时候启动或者停止相关服务.))
    */
    if(pid==-1)
    {
        perror("process creation failed\n");
        exit (0);
    }
    if(pid>0)
    {
        exit(0);
    }
    setsid();//2.创建一个新的会话,并且担任该会话组的组长(会话组长调用这个函数会失败,但是这时进程是刚刚建立的,不可能是会话组长)
    /*
    子继承了父所有的会话信息,进程组信息,和终端还有牵扯
    要让子进程成为新的会话组长,进程组长,
    摆脱原会话的控制,让进程摆脱原进程的控制,
    会话对终端的独占性,进程摆脱原控制终端的控制。
    */
    pid=fork();//3.再产生一个子进程
    /*
    这时子进程脱离终端了,是无终端的会话组长了
    但是组长还可以重新申请打开一个终端;
    所以再fock一个子进程,这个子进程一定不是会话组长
    关闭父进程,则这个进程一定不会被终端控制
    */
    if(pid==-1)
    {
        perror("process creation failed\n");
        exit (0);
    }
    if(pid>0)
        exit(0);
    for(i=0;i<NOFILE;close(i++));//4.进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们(NOFILE允许的最大文件描述符):
    chdir("./");//5.进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如
    umask(0);//6.进程从创建它的父进程那里继承了文件创建屏蔽字。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件屏蔽字清楚:
    signal(SIGCHLD,SIG_IGN);//7.这里就是上面讲的(处理SIGCHLD信号,通知内核,父不接收对子进程的结束信号)
    //------------------守护进程-------OVER------------------------//


    char *argv[3];
    argv[0]="qwer.txt";
    argv[1]="123";
    argv[2]=NULL;
    while(1)//8.守护进程检测(我在这里是将一个字符串不断地追加在一个文件里,如果成功就可以通过文件来看到)
    //其实这里完全可以不用去打开新程序,但是为了熟悉一下操作;
    {
        pid=fork();
        if(pid==-1)
        {
            exit(1);
        }
        if(pid==0)
        {
            execv("asd",argv);//执行新程序,将之前的那块内存完全换成我调用的新的程序(记住,是是直接换程序,如果那个程序结束了,那就直接退出了不会返回来),但是ID什么的不变;
            /*
            execv(可执行文件名,传给下一个程序的argv字符串数组)(注意必须要以NULL结束);
            */
        }
        if(pid>0)
        {
            int stat_val;//子进程结束的状态码;
            pid_t child_pid;//
            child_pid=wait(&stat_val);//让父进程等待子进程
            if(WIFEXITED(stat_val));//获取子进程返回停止状态宏函数;虽然这获取没什么用。。。但是记录一下
        }
    }
    return 0;
}

下面是execv打开的程序,记得编译的时候将可执行文件命名为asd,不要问我为什么。。。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<signal.h>        //sigal
#include<sys/stat.h>
#include<time.h>
#include<syslog.h>
#include<sys/param.h>
int main(int argc,char *argv[])
{
    int fp;
    fp=open(argv[0],O_RDWR|O_CREAT|O_APPEND,0777);
    write(fp,argv[1],sizeof(char)*strlen(argv[1]));
    close(fp);
    sleep(3);
    exit (0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值