zoukankan      html  css  js  c++  java
  • linux守护进程的创建

    下面的完成了这样一个功能,创建一个守护进程,每个一秒在/tmp目录下的文件peng.txt中记录当前系统时间。

    一、守护进程

    守护进程是linux中的后台服务进程,在系统启动时开始运行,在系统关闭时终止。Linux系统中的大多数服务进程都是由守护进程实现的。

    二、创建守护进程

    • 创建子进程,父进程退出

    此时,子进程变成孤儿进程,在后台运行。此时,子进程表面上脱离了终端(如bash),但是实际上却没有,因为其PGID和SID都是原来的没变。

    • 在子进程中创建新的会话

    调用setsid()函数,这样,子进程的GID和sid就都等于子进程pid了,它使子进程完全独立出来,可以使用 kill –9 pid,将其杀死。

    • 改变进程的工作目录为根目录

    首先要知道工作目录与当前目录的区别,工作目录默认是当前目录,比如执行函数open(“1.c”,……),时,系统会自动到默认的工作目录(即当前目录)中读取或者创建文件 1.c ,但是通过调用函数 chdir(“/tmp”),可以将工作目录变成/tmp,此后,如果再执行open(“1.c”,……),系统就回到/tmp目录下面读取或者创建文件 1.c;

    其次,为什么有改变工作目录?原因是,守护进程的工作目录不可以被卸载!假如你把U盘挂载到了机器上,你没改工作目录,U盘上有一个守护进程的程序,你运行了,那么U盘所挂载的目录就是该守护进程的工作目录,假如守护进程中有写文件和读文件操作,你的U盘就没法卸载了,假如你把工作目录改成/tmp,而/tmp无法卸载,运行U盘上的守护进程后,再与U盘无关,此时你可以卸载U盘,而不会对该守护进程有什么影响,该守护进程已经在内存中了。

    通常将守护进程的工作目录设置成 “/”或者“/tmp ”,可以看看/tmp 目录的权限是否够用,一般是 0777。

    • 重设文件权限掩码

    将文件权限掩码设置为umask(0),这样可以增加守护进程的灵活性

    • 关闭文件描述符

    因为创建子进程时,父进程已经打开了若干文件(比如stdin、stdout、stderr),而守护进程用不到这些文件,所以应该关闭。因此,守护进程已经无法使用诸如printf 、scanf、gets等等。

    源代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <time.h>
    
    int main()
    {
        pid_t pid;
        int i;
        FILE *fp;
        time_t t;
    
        if ((pid = fork()) == -1)  //创建子进程
        {
            perror("fork");
            exit(-1);
        }
    
        if (pid > 0) exit(0);   //pid>0是父进程,父进程退出
    
        setsid();         //在子进程中建立新会话,使子进程完全独立
        chdir ("/tmp");   //改变工作目录为/tmp
        umask(0);        //重设文件权限掩码
        for (i = 0; i < getdtablesize(); i++)   //关闭已经打开的文件,包括stdin、stdout和stderr,getdtablesize的返回值为固定值
            close(i);                            //注意getdtablesize()不是函数,而是一个宏定义,为常数。
    
        if ((fp = fopen("time.txt", "a")) == NULL)  //打开要写的文件
            exit(-1);
    
        while (1)
        {
            sleep(1);
            t = time(NULL);  //获取系统时间
            fprintf(fp, "%s", ctime(&t));//ctime将time转化为标准格式字符串,返回字符串首地址
            fflush(fp);  //因为是全缓存,所以为保证实时性,用该用fflush进行刷新。
        }
    
        return 0;
    }
  • 相关阅读:
    《C#高级编程》读书笔记(十五):任务、线程和同步之二 任务
    sklearn训练模型的保存与加载
    机器学习中样本不平衡的处理方法
    剑指Offer(四):重建二叉树
    剑指Offer(三):从尾到头打印链表
    机器学习笔记(一)----基本概念
    100 个网络基础知识普及,看完成半个网络高手
    协方差基本概念及公式
    正态分布基本概念及公式
    np.random.multivariate_normal方法浅析
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/2945049.html
Copyright © 2011-2022 走看看