关于守护进程

关于守护进程
  • 为什么要设置守护进程?
    • 守护进程———>就是脱离用户终端的后台进程
    • 当我们关闭终端时,该进程也不会退出。举个例子:比如我们远程登录一个linux系统,通过终端运行服务器程序,此时我们关闭终端退出来的时候,我们希望该服务器程序依然运行。此时就需要使该服务器进程是守护进程。
    • 他是Linux的一种长期运行的后台服务进程。我们常见的httpd,named,sshd等服务都是以守护进程Daemon方式运行的,通常服务名称以字母d结尾。
    • 与普通进程相比的特点有:
    • 无需终端控制(不需要与用户交互)
    • 在后台运行
    • 生命周期比较长,一般是随系统启动和关闭
  • 守护进程的实现步骤:
    • 1.让进程在后台执行。
    • 方法是:调用fork产生一个子进程,让父进程退出,子进程就成了孤儿进程 ,使子进程成为后天进程。
    • 2.在子进程中创建新的会话,脱离控制终端
    • 刚开始,一个会话组id对应一个终端,会话组里包含前台进程组和后台进程组。当关闭终端时,会话组里的所有进程都关闭。所以子进程要想脱离终端时,使用setsid()就可创建新的会话组,并且担任该会话组的组长,独立出终端。
    • 3.禁止进程重新打开控制终端
    • 此时,进程已经成为一个无终端的会话组长,但他还可以重新申请打开一个终端,为了避免这样,可以使进程不再是会话组长来实现,在一次通过fork创建新的子进程,是调用fork的进程退出
    • 4.关闭不再需要的文件描述符
    • 创建的子进程从父进程继承打开的文件描述。如果不关闭,会有问题。先得到最高文件描述符值,然后用一个循环程序,关闭0到最高文件描述符值的所有文件描述符。
    • 5.改变当前工作目录为根目录
    • 子进程会继承父进程的工作目录,由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后使用会造成很多的麻烦。所以需要使用chdir改变子进程的工作目录为根目录。
    • 4.重设文件权限掩码
      文件权限掩码是屏蔽掉文件权限中的对应位。由于使用fork()函数新创建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了很多的麻烦(比如父进程中的文件没有执行文件的权限,然而在子进程中希望执行相应的文件这个时候就会出问题)。因此在子进程中要把文件的权限掩码设置成为0,即在此时有最大的权限,这样可以大大增强该守护进程的灵活性。设置的方法是:umask(0)
    • 6.守护进程的退出,信号注册
      通过kill命令,使守护进程退出,通常需要signal注册信号处理函数,进行退出处理。
  • 代码示例:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/param.h>
#include<sys/stat.h>
#include<time.h>
#include<syslog.h>
int init_daemon(void)
{
    int pid;
    int i;
    /*忽略终端I/O信号,STOP信号*/
    signal(SIGTTOU,SIG_IGN);
    signal(SIGTTIN,SIG_IGN);
    signal(SIGTSTP,SIG_IGN);
    signal(SIGHUP,SIG_IGN);
    pid=fork();
    if(pid>0)
        exit(0);//结束父进程,使进程成为后台进程
    else if(pid<0)
        return -1;
    /*建立一个新的进程组,使子进程成为这个进程的首进程,使该进程脱离所有终端*/
    setsid();
    /*再次新建一个子进程,退出父进程,保证该进程不是进程组长,同时让该进程无法再打开一个新的终端*/
    pid=fork();
    if(pid>0)
        exit(0);
    else if(pid<0)
        return -1;
    /*关闭所有从父进程继承的不再需要的文件描述符*/
    for(i=0;i<NOFILE;close(i++))
        ;
    /*改变工作目录,使进程不与任何文件联系*/
    chdir("/");
    /*将文件屏蔽字设置为0*/
    umask(0);
    /*忽略SIGCHLD信号*/
    signal(SIGCHLD,SIG_IGN);
    return 0;
}
int main(void)
{
    time_t now;
    init_daemon();
    syslog(LOG_USER|LOG_INFO,"测试守护进程!\n");
    while(1)
    {
        sleep(8);
        time(&now);
        syslog(LOG_USER|LOG_INFO,"系统时间:\t%s\t\t\n",ctime(&now));
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的守护进程(Daemon Process)是指在后台运行的进程,它们不会受到终端或用户的交互影响,通常用于执行一些长时间运行的任务或服务。Python中可以通过设置进程的daemon属性来创建守护进程。 要创建守护进程,可以使用`multiprocessing`模块或`threading`模块。下面是使用`multiprocessing`模块创建守护进程的示例代码: ```python import multiprocessing import time def worker(): print("守护进程开始运行") time.sleep(5) print("守护进程结束运行") if __name__ == '__main__': process = multiprocessing.Process(target=worker) process.daemon = True # 设置为守护进程 process.start() time.sleep(2) print("主进程结束") ``` 在上面的代码中,我们创建了一个名为`worker`的函数作为守护进程的任务。通过设置`process.daemon = True`将进程设置为守护进程。然后使用`process.start()`启动守护进程。在主进程中,我们暂停了2秒后结束,此时守护进程也会随之结束。 需要注意的是,守护进程会随着主进程的结束而结束,而无论守护进程是否已经执行完任务。因此,在使用守护进程时需要确保主进程不会过早地结束,否则守护进程可能无法完成任务。 除了`multiprocessing`模块,`threading`模块也提供了创建守护线程的方式,使用方法类似。不同之处在于,线程是共享进程的内存空间的,而进程拥有自己独立的内存空间。 希望以上内容能够对你有所帮助。如果你有更多关于守护进程的问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值