百色金融新闻网
您的位置:百色金融新闻网 > 金融新闻 > Linux进程间关系之守护进程-12341234

Linux进程间关系之守护进程-12341234

作者:百色金融新闻网日期:

返回目录:金融新闻

最新资讯《Linux进程间关系之守护进程-12341234》主要内容是12341234,概念守护进程也称精灵进程,是运行在后台的一种特殊进程。守护进程独立于控制终端并且周期性的执行某种任务或者等待处理某些打算的事件。可认为守护进程目的就是防止终端产生的一些信号让进程退出特点所有的守护进程都没有控制终端,其终端名(TTY)设置为问号(?)。自成会话,自成进程组。,现在请大家看具体新闻资讯。

概念

守护进程也称精灵进程,是运行在后台的一种特殊进程。守护进程独立于控制终端并且周期性的执行某种任务或者等待处理某些打算的事件。可认为守护进程目的就是防止终端产生的一些信号让进程退出

特点

  • 所有的守护进程都没有控制终端,其终端名(TTY)设置为问号(?)。

  • 自成会话,自成进程组。不与其他会话或进程组相互关联,干扰。所以一般一个守护进程的进程ID,组ID,会话ID都相同。(自成进程组这点说的也不太严谨,若父进程是守护进程,父进程fork的子进程也是守护进程。这时父子进程属于同一进程组)

  • 命令以‘d’结尾

  • 守护进程不受用户登录注销的影响,当你注销或者重登后,守护进程一直在运行。

  • 生存期长,在系统引导装入时启动,仅在系统关闭时终止。

  • 在后台运行(原因可归结于没有控制终端)

  • 大多数的守护进程都以root特权运行。

Linux大多数服务器都是由守护进程实现。如:web,http,阿帕奇等。

守护也完成许多系统任务,如:作业规划进程crond。

用户层守护进程

用户层没有终端的原因可能是调用了setsid(会在下面细讲)函数的结果。大多数用户层守护进程都是进程组的组长进程以及会话的会话首进程,而且是这些进程组和会话中的唯一进程(rsyslogd是一个例外)。

Linux进程间关系之守护进程

我们通常所说的1号进程init就是一个系统守护进程。除了其他工作外,主要负责启动各运行层析的系统服务。这些服务通常是在它们自己拥有的守护进程的帮助下实现的。此外,init就是用户层进程的父进程。

(上图中的各选项与本图中的头部一一对应)

Linux进程间关系之守护进程

内核线程(内核守护进程)

(其实也叫内核进程,Linux没有真正意义上的线程,都是用进程模拟实现,轻量级进程。)

内核守护进程以无终端的方式启动,凡是在TPGID一栏写着-1的进程都是没有控制终端的进程,也就是守护进程。在COMMAND列[ ]括起来的名字表示内核线程,这些线程在内核创建,没有用户空间代码,因此没有程序文件名和命令行, 通常采用以k开头的名字,表Kernel。对于需要在进程上下文执行工作但却不被用户层进程上下文调用的每一个内核组件,通常都有它自己的内核守护进程。

Linux进程间关系之守护进程

Linux通常使用一个叫kthreadd的特殊内核进程来创建其他内核进程,所以kthreadd表现为其他内核进程的父进程。

Linux进程间关系之守护进程

由此我们可看到kthread的进程ID为2。这也就解释了为什么在上图中内核进程(内核线程)的父进程ID(PPID)都为2了。

创建守护进程

函数setsid,创建守护进程很关键的一步就是调用setsid函数创建一个新的会话(Session),并让当前的进程称为这个会话的Leader,即会话首进程。

#include<stdio.h>pid_t setsid(void)123123

返回值:若成功,返回进程组ID;若失败,返回-1。

执行方式:直接在要设置的进程里调用。

这个函数的执行结果为:

  • 创建一个新会话,使该进程变成新会话的会话首进程(会话首进程也可理解为创建会话的进程),此时,该进程是当前会话的唯一进程

  • 使该进程称为一个新进程组的组长进程,进程组ID就是该进程的进程ID。

  • 使该进程没有控制终端,如果在调用setsid之前有,那么就切断控制终端与当前进程的联系。

  • 当前进程的进程ID,进程组ID,会话ID都相等。

setsid函数调用之前有一个特殊要求:该进程不能是一个进程组的组长进程。如果是,函数调用将返回出错。

所以我们通常为了防止出现这种情况会用以下做法:让一个进程fork出一个子进程,然后立即将父进程终止,而子进程继续。子进程的进程ID是新分配的,子进程的PCB集成了父进程的进程组ID,所以两者不可能相等。这样就保证了子进程不是一个进程组的组长。

除了以上两种操作外,创建一个守护进程还需要其他几项工作。下面我将完全的步骤列出来:

  • 调用umask函数将当前文件模式创建屏蔽字为一个已知值(通常为0)。在上面提到过,我们要操作的进程是一个子进程。而子进程从父进程的PCB继承过来的文件模式创建屏蔽字可能会屏蔽某些权限。而加入我们要创建的守护进程正好需要这些权限的话就会造成很麻烦的问题。另一方面,如果守护进程调用了库函数创建了文件,那么文件模式创建屏蔽字应该设置为更强的(如007)。因为库函数不允许调用者通过一个显式的函数参数来设置权限。

  • fork子进程,并且结束父进程。

  • 调用setsid函数。创建一个会话,使当前进程称为一个会话的首进程,一个进程组的组长进程,一个没有控制终端的进程。

  • 调用函数chdir将当前进程的工作目录更改为根目录或者某个指定位置。因为子进程从父进程继承来的工作目录可能是在一个挂载的文件系统中,而守护进程在系统再次引导前是一直存在的,如果不更改,那么挂载的文件系统就一直卸载不了。

  • 调用fclose函数关闭不在需要的文件描述符(0,1,2等)。使守护进程不再持有从父进程继承来的任何文件描述符。或者还可以将文件描述符重定向到文件(/dev/null)。这样相当于将当前进程的标准输入,标准输出,标准错误都失效。关闭文件描述符的原因是守护进程是与控制终端没有任何联系的,并且它是在后台运行。后台并没有接受它输入输出也无处显示,我们不希望在终端上简单守护进程的输出,用户也不想在终端上的输入被守护进程读取。

fd0 = open("/dev/null",O_RDWR);dup2(fd0,1); //dup2的作用就是文件描述符重定向dup2(fd0,2);12341234

创建实例

void mydaemon(){ umask(0); pid_t id = fork(); if(id > 0 ) 
{ exit(1); }
printf("Debug\\n"); setsid(); //创建新会话
chdir("/"); //将工作目录设置为根目录 close(0); //关闭文件描述符
close(1);
close(2); signal(SIGCHLD,SIG_IGN);//忽略SIGCHLD信号}int main(){
mydaemon(); while(1); //死循环,方便我们查看 return 0;}12345678910111213141516171819202122232425262728291234567891011121314151617181920212223242526272829

编译运行后我们可以利用ps axj指令查看这个守护进程。

Linux进程间关系之守护进程

上面为我们创建守护进程的一种方式,其实Linux为我们提供了专门的函数接口来创建守护进程。

函数daemon():

#include <unistd.h>int daemon(int nochdir, int noclose);12341234

两个参数,第一个参数nochdir如果设置为0的话表示将工作目录改为根目录。第二个参数noclose如果设置为0的话就将文件描述符重定向到/dev/null文件。与上面原理相似。

所以,简单的执行下面代码就可以创建一个守护进程。

#include<stdio.h>#include<unistd.h>int main(){ daemon(0,0); while(1);//死循环为了方便查看 return 0;}1234567891012345678910

是不是感觉好坑啊?是很坑,但是上面的一大堆道理是必须要懂的!

拓展:fork一次和fork两次?

我们利用第一种比较繁琐的方式创建守护进程时,是利用父进程fork一次创建了子进程。有时编写守护进程时需要fork两次,关于这样做的原因有以下两种说法:

  1. 避免出现僵尸进程,进程有一种状态叫做ZOMBIE,称为僵尸状态。通常是因为子进程异常或正常退出后没有父进程(调用wait或wiatpid)来给它收尸,而导致子进程成为僵尸进程。虽然我们的做法是fork子进程后立即将父进程退出,子进程会被1号进程init接管,并不会出现僵尸进程。但是我们不能认为父进程仅仅是为了创建子进程而出现的,父进程也有他自己的事情要做。如果父进程因为执行某段程序而阻塞,而子进程已经政策结束或异常退出,此时子进程并没有被init进程接收。子进程就变成了一个无人收尸的僵尸进程

  2. 避免打开新的终端。我们知道,守护进程是没有控制终端的。先说明一下,打开终端的一个前提条件是该进程必须是会话组长。而我们fork一次并且setsid的儿子进程正好是会话组长。fork第二次,令孙子进程担任守护进程。而且孙子子进程ID != 儿子进程ID(会话组长)。这样就防止了守护进程再次打开新的控制终端。

相关阅读

  • Linux进程间关系之守护进程-12341234

  • 百色金融新闻网金融新闻
  • 12341234,概念守护进程也称精灵进程,是运行在后台的一种特殊进程。守护进程独立于控制终端并且周期性的执行某种任务或者等待处理某些打算的事件。可认为守护进程目的就是防止终
关键词不能为空

经济新闻_金融新闻_财经要闻_理财投资_理财保险_百色金融新闻网