python实现守护进程_守护进程原理及Python实现

守护进程原理及Python实现

守护进程,不依赖于终端,在后台运行的程序,通常称为daemon(ˈdiːmən或ˈdeɪmən)。

一些常见的Linux软件通常都是已守护进程的方式运行,比如:

nginx

redis

memcached

守护进程的原理:

通过fork() 复刻出子进程,并通过setsid()创建新会话,成为会话首领;同时结束原来的父进程,使得复刻出来的子进程脱离终端而运行。

守护进程Python代码实现:

def daemon_start(self):

try:

# 第1次fork,并结束父进程

pid = os.fork()

if pid > 0:

sys.exit(0)

except Exception as e:

sys.exit(1)

# 创建新会话,并成为会话首领

os.setsid()

os.chdir(self.workdir)

os.umask(self.umask)

try:

# 第2次fork,结束当前这个子进程,fork出来的孙子进程由于不是进程首领,无法再次获取终端(这里的子进程,孙子进程都是相对于最开始的那个初始进程而言)

pid = os.fork()

if pid > 0:

sys.exit(0)

except Exception as e:

sys.exit(1)

def handle_exit(signum, _):

sys.exit(0)

# 孙子进程注册信号处理方式

signal.signal(signal.SIGINT, handle_exit)

signal.signal(signal.SIGTERM, handle_exit)

signal.signal(signal.SIGHUP, signal.SIG_IGN)

# 孙子进程是守护进程,不存在标准输入输出,所以关闭。

sys.stdin.close()

核心函数说明:

os.fork(): 对进程进行复刻;值得特别注意的是fork之后,原来的进程并没有终止,而是继续存在,被成为父进程;也就是说,在fork成功后,一共会存在2个进程,1个是原来的进程,称为父进程,1个是新创建的进程,称为子进程。父进程和子进程都会从fork的位置开始继续向下执行,不同的是父进程中,得到的fork返回值为子进程的进程号,而子进程中得到的是0。通过这个返回值,就能判断哪个是父进程,哪个是子进程。以上这点值得特别注意,这与我们以往理解的程序执行逻辑完全不同。

os.setsid():创建新的会话,并成为会话首领。

os.chdir():修改当前工作目录路径,防止目录被移除导致守护进程异常。

os.umask():设置文件创建模式屏蔽字,使得创建文件不受系统默认权限的影响。

常见问题:

1.第1次fork子进程已经脱离终端,为什么还要第2次fork,第2次fork是否必须?

第2次fork并不是必须的,实际上,很多流行的开源软件的守护进程并没有进行第2次fork。第2次fork的目的在于防止第1次fork出来的进程再次获得终端,第2次fork后,产生的孙子进程不再是会话首领,也就没有再次获得终端的能力。

void daemonize(void) {

int fd;

if (fork() != 0) exit(0); /* parent exits */

setsid(); /* create a new session */

/* Every output goes to /dev/null. If Redis is daemonized but

* the 'logfile' is set to 'stdout' in the configuration file

* it will not log at all. */

if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {

dup2(fd, STDIN_FILENO);

dup2(fd, STDOUT_FILENO);

dup2(fd, STDERR_FILENO);

if (fd > STDERR_FILENO) close(fd);

}

}

2.进程已经脱离终端,如何让它停止或者重启?

每一个进程都有一个进程id,即pid,通常程序启动后,会把pid写入到/var/run/目录下的某个文件里,通过发送信号量给pid,即可操作相关进程。示例代码中的“进程注册信号处理方式”就是用来响应信号量的,守护进程可以针对不同的信号,做出不同的反应。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值