千家信息网

Linux系统守护进程怎么理解

发表于:2024-11-14 作者:千家信息网编辑
千家信息网最后更新 2024年11月14日,这篇文章主要为大家分析了Linux系统守护进程怎么理解的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"Linux系统守
千家信息网最后更新 2024年11月14日Linux系统守护进程怎么理解

这篇文章主要为大家分析了Linux系统守护进程怎么理解的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"Linux系统守护进程怎么理解"的知识吧。

什么是守护进程?例如淘宝、支付宝等必须7*24小时不停的运行,这就是一个非常典型的守护进程。

1、查看系统中的进程

 ps axj1

参数a表示不仅列当前用户的进程,也列出所有其他用户的进程, 参数x表示不仅列有控制终端的进程,也列出所无控制终端的进程, 参数j表示列出与作业控制相关的信息。

凡是TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。在COMMAND一列用[]括起来的 名字表示内核线程,这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行, 通常采用以k开头的名字,表示Kernel。init进程我们已经很熟悉了,udevd负责维 护/dev目录下的设备⽂文件,acpid负责电源管理,syslogd负责维护/var/log下的日志文件,可以看出,守护进程通 常采用以d结尾的名字,表示Daemon。

2、setsid函数 1>创建守护进程最关键的一步是调用setsid函数创建一个新的Session,并成为Session Leader。

 #include pid_t setsid(void);12

返回值:该函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。

2>需要注意的是,,调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。 解决办法:先fork再调用setsid,fork创建的子进程和父进程在同一个进 程组中,进程组的Leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子 进程中调用setsid就不会有问题了。

3>成功调用该函数的结果是: \1. 创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。 \2. 创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。 \3. 如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。

3、创建守护进程的步骤 1>调用umask将文件模式创建屏蔽字设置为0.

 umask(0);//umask必须清0,否则创建文件受系统默认权限的影响1

文件权限掩码是屏蔽掉文件权限中的对应位。由于使用fork()函数新创建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了很多的麻烦(比如父进程中的文件没有执行文件的权限,然而在子进程中希望执行相应的文件这个时候就会出问题)。因此在子进程中要把文件的权限掩码设置成为0,即在此时有最大的权限,这样可以大大增强该守护进程的灵活性。

2>调用fork,父进程退出(exit)。 原因: 1)如果该守护进程是作为一条简单的shell命令启动的,那么⽗父进程终止使得shell认为该命令已经执行完毕。 2)保证子进程不是一个进程组的组长进程。

3>调用setsid创建一个新会话。 setsid会导致: 1)调用进程成为新会话的首进程。 2)调用进程成为一个进程组的组长进程 。 3)调用进程没有控制终端。(再次fork一次,保证daemon进程,之后不会打开tty设备)

调用setsid的原因: 由于创建守护进程的第一步是调用fork()函数来创建子进程,再将父进程退出。由于在调用了fork()函数的时候,子进程拷贝了父进程的会话期、进程组、控制终端等资源、虽然父进程退出了,但是会话期、进程组、控制终端等并没有改变,因此,需要用setsid()韩式来时该子进程完全独立出来,从而摆脱其他进程的控制。

4>将当前工作目录更改为根目录。 防止当前目录有一个目录被删除,导致守护进程无效。 使用fork()创建的子进程是继承了父进程的当前工作目录,由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后使用会造成很多的麻烦。因此通常的做法是让"/"作为守护进程的当前目录,当然也可以指定其他的别的目录来作为守护进程的工作目录。

5>关闭不再需要的文件描述符。 同文件权限码一样,用fork()函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些文件被打开的文件可能永远不会被守护进程读写,如果不进行关闭的话将会浪费系统的资源,造成进程所在的文件系统无法卸下以及引起预料的错误。

如:关闭标准输入流、标准输出流、标准错误流。

 close(0); close(1); close(2);123

6>其他:忽略SIGCHLD信号。

 signal(SIGCHLD,SIG_IGN);1

4、自己创建守护进程:

   1 /**************************************   2 *文件说明:mydaemon.c   3 *作者:段晓雪   4 *创建时间:2024年11月20日 星期三 12时26分43秒   5 *开发环境:Kali Linux/g++ v6.3.0   6 ****************************************/   7   8 #include   9 #include  10 #include  11 #include  12 #include  13 #include  14  15 void mydaemon()  16 {  17     umask(0);//将文件模式创建屏蔽字设为0  18     pid_t pid = fork();//创建子进程  19     if(pid == -1)  20         perror("fork error");  21     else if(pid == 0)//child  22     {  23         setsid();//创建新会话  24         if(chdir("/")ps axj | grep mydaemon查看精灵进程: 5、调用系统函数daemon创建守护进程 #include int daemon(int nochdir, int noclose);121>daemon函数主要用于希望脱离控制台,以守护进程的形式在后台运行的程序。 2>当nochdir为0时,daemon将更改当前进程的目录为root("/")目录。 3> 当noclose为0时,daemon将进程的STDIN,STDOUT,STDERR都重定向到/dev/null。 /dev/null:linux下的黑洞,写入的所有数据会直接丢弃。用daemon函数创建守护进程:   1 /**************************************   2 *文件说明:daemon.c   3 *作者:段晓雪   4 *创建时间:2024年11月22日 星期五 06时53分52秒   5 *开发环境:Kali Linux/g++ v6.3.0   6 ****************************************/   7   8 #include   9 #include  10  11 int main()  12 {  13     daemon(1,1);//创建守护进程  14     while(1);  15     return 0;  16 }12345678910111213141516三、如何杀死守护进程?1> 利用ps axj | grep 守护进程名字找到相应的守护进程,然后用kill -9 进程号将对应进程杀死。 2>利用ps -ef命令查找相应的守护进程,再用kill命令将其杀死。  …… 3>也可创建shell脚本对进程的启动、关闭、重启进行自动管理。四、为什么有人创建守护进程会fork两次?一个daemon函数常见的实现: int daemon(void)   {       pid_t pid = fork();  //第一次fork      if( pid != 0 )         exit(0);//parent        //first children       if(setsid() == -1)       {          printf("setsid failed\n");          assert(0);          exit(-1);       }        umask(0);        pid = fork();  //第二次fork      if( pid != 0)         exit(0);        //second children       chdir ("/");        for (int i = 0; i可以看到上面的代码里我fork了两次,虽然说这并不是必须的,但是这的确是对守护进程做出了一些更优化的操作。首先第一次fork:这里第一次fork的作用就是让shell认为这条命令已经终止,不用挂在终端输入上;再一个是为了后面的setsid服务,因为调用setsid函数的进程不能是进程组组长(会报错Operation not permitted),如果不fork子进程,那么此时的父进程是进程组组长,无法调用setsid。所以到这里子进程便成为了一个新会话组的组长。第二次fork:第二次fork是为了避免后期进程误操作而再次打开终端。因为打开一个控制终端的前提条件是该进程必须为会话组组长,而我们通过第二次fork,确保了第二次fork出来的子进程不会是会话组组长。下面罗列一下控制终端会产生哪些信号。程序中只要处理好这些信号,同样能达到上面函数实现的目的。//后台进程读取/写入终端输入产生下面两个信号,或者控制终端不存在情况读取和写入会产生   signal(SIGTTOU, SIG_IGN);    signal(SIGTTIN, SIG_IGN);12//按CTRL-C ,CTRL-\ CTRL-Z会向前台进程组发送下面这些信号    signal(SIGINT,  SIG_IGN );    signal(SIGQUIT, SIG_IGN );    signal(SIGTSTP, SIG_IGN );123//终端断开,会给会话组长或孤儿进程组所有成员发送下面信号    signal(SIGHUP,  SIG_IGN );1还有有些信号也可以由终端shell产生,需要关注 signal(SIGCONT, SIG_IGN ); signal(SIGSTOP, SIG_IGN );12上面这些信号,应该有些程序缺省处理(SIG_DFL)本身动作就是忽略(SIG_IGN),不是退出进程。不过按照上面写也不会造成什么问题。至此关于Linux系统守护进程的具体 内容分享完毕,欢迎大家在评论区留言。以上就是良许教程网为各位朋友分享的Linux系统相关内容。想要了解更多Linux相关知识记得关注公众号"良许Linux",或扫描下方二维码进行关注,更多干货等着你!

关于"Linux系统守护进程怎么理解"就介绍到这了,更多相关内容可以搜索以前的文章,希望能够帮助大家答疑解惑,请多多支持网站!

进程 文件 终端 控制 函数 系统 目录 信号 权限 组长 命令 就是 内容 名字 程序 新会 参数 更多 标准 用户 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 浙江运营网络技术哪家好 网络数据库中的数据寿命 农安先进网络技术咨询排名靠前 天龙八部少年游服务器在哪个大区 做谷歌广告需要服务器吗 英语软件开发教程 服务器的用户名是什么 系统要带数据库吗 画网络安全手抄图片 网络安全周英语 sql数据库怎么看内容 辽宁等离子套料软件开发商 网络安全市场 2021 网络技术对我们的影响 结构化日志数据用什么数据库 我所学的专业是计算机网络技术 免疫组化数据库的生信 将第一条数据插入到数据库中 html输出数据库中的表格 数据库查询对象名无效 上虞电力监控软件开发 介绍CS和BS模式服务器的书籍 金现代软件开发工程师前景 帝国神话官方服务器和自定义 做谷歌广告需要服务器吗 网络安全支队是什么 网络安全周期线上答题 数据库的市场大概是2 java用户注册并保存到数据库 凌空网络技术有限公司怎么样
0