0


【linux 多进程并发】0301 Linux创建后台服务进程,daemon进程,自己的进程可以被一号进程接管啦

0301 Linux创建后台进程

专栏内容

  • postgresql使用入门基础
  • 手写数据库toadb
  • 并发编程

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

在这里插入图片描述

一、概述


开发一款服务端程序,它往往以服务进程方式运行,也就是我们常说的后台进程。

在linux 下使用

top

命令,可以看到实际已经有很多的进程一直在运行中,这些进程就是后台服务进程。

那么如何让自己的程序以后台服务进程的方式运行呢, 同时如何管理后台服务进程,对它们进程启动,重启,停止等操作,

本节内容就来详细聊一聊后台服务进程的那些事儿。

二、创建后台服务进程原理


我们先来用

ps

命令看一个后台进程;

[senllang@hatch src]$ ps -ef|grep toadb |grep -v grep
senllang  70306410 Oct14 pts/16   00:07:09 ./toadb-0-01 -M 2
toadb

是一个数据库,它在后台运行,是一个从零开始手写的数据库,详细介绍见toadb基础架构模型,想练手的同学可以关注toadb专栏。

可以看到后台服务进程的进程PID为

703064

,而父进程PID为

1

;

我们再来看一下1号进程是什么?

[senllang@hatch src]$ ps -ef|moreUID          PID    PPID  C STIME TTY          TIME CMD
root           100 Oct08 ?        00:00:17 /usr/lib/systemd/systemd --switched-root --system --deserialize 18

可以看到1号进程,就是systemd服务进程。

根据之前开始介绍linux进程家族体系的内容,1号进程是所有用户进程起源;

同时一个进程的父进程提前结束时,它就会被1号进程接管,也就是自动变化1号进程的子进程,此时就会转到后台运行。

三、创建后台服务进程的方法


让程序在后台执行,我们知道有很多方法,如在执行命令后面加

&

, 使用

nohup

命令,或者是

bg

命令等等,

但这些仅仅是程序在后台执行,而程序的父进程还是当前的shell窗口,当shell关闭时,程序也有可能会结束。

在这里插入图片描述

如何创建一个后台服务进程,或者叫做 daemon进程,让它的父进程为systemd进程,下面就一起来看看。

3.1 程序代码

下面我们编写一段演示程序。

/*
 * ex020301_daemon.c
 */#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<unistd.h>#include<errno.h>#include<string.h>voiddaemon_fork();intmain(int argc ,char*argv[]){daemon_fork();sleep(10);return0;}voiddaemon_fork(){int pid =-1;
        pid =fork();if(pid <0){printf("fork error[%s]\n",strerror(errno));exit(-1);}elseif(pid >0){// parent exit.exit(0);}else{// child daemonreturn;}}

说明

  • daemon进程主要在daemon_fork函数中,函数返回后,当前就在daemon进程中;
  • 用sleep(10)来模拟服务进程的处理,可以用实际的服务程序代码替代;

下面看看daemon_fork函数,

  • 用fork创建了一个子进程,这与前几节介绍的fork示例类似;
  • 在父进程分支中,直接调用exit退出了;
  • 而子进程分支中,我们选择了函数返回;也就是调用该函数后,后续的代码是子进程中执行了;

3.2 运行分析

编译执行

[senllang@hatch ex_0201]$ gcc ex020301_daemon.c -o extest
[senllang@hatch ex_0201]$ ./extest &[1]1074458

我们使用后台执行,可以看到后台任务号为1。

后台进程情况查看

[senllang@hatch ex_0201]$ ps -ef|grep extest |grep -v grep 
senllang 107445910 08:44 pts/8    00:00:00 ./extest

[1]+  Done                    ./extest

可以看到当前进程PID为

1074459

, 而父进程PID为

1

,也就是它已经被systemd接管了。

原理分析

当我们创建子进程后,父进程不会等待子进程,而是直接结束了,此时子进程就会被systemd接管了,

也就是作为后台服务进程继续运行,最终子进程退出时资源回收由systemd进程来负责。

四、总结


通常我们在终端启动程序,该程序的父进程一般是终端进程,这样在终端退出时,会产生像SIGHUG信号发给所有子进程,子进程默认处理是退出。

我们要创建后台服务进程时,必需让进程与终端无关,这就是示例代码中经过一次fork之后,父进程退出,而子进程让systemd接管的真正作用。

本章节代码位于gitcode, 路径为: multiProcess/ex02_multiprocess, 有兴趣的同学可以下载测试,当然别忘了点个小星星。

结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

标签: linux 运维 服务器

本文转载自: https://blog.csdn.net/senllang/article/details/143165596
版权归原作者 韩楚风 所有, 如有侵权,请联系我们删除。

“【linux 多进程并发】0301 Linux创建后台服务进程,daemon进程,自己的进程可以被一号进程接管啦”的评论:

还没有评论