linux进程学习总结 孤儿进程和守护进程非诚

上传人:小** 文档编号:89125237 上传时间:2019-05-18 格式:DOC 页数:11 大小:29KB
返回 下载 相关 举报
linux进程学习总结 孤儿进程和守护进程非诚_第1页
第1页 / 共11页
linux进程学习总结 孤儿进程和守护进程非诚_第2页
第2页 / 共11页
linux进程学习总结 孤儿进程和守护进程非诚_第3页
第3页 / 共11页
linux进程学习总结 孤儿进程和守护进程非诚_第4页
第4页 / 共11页
linux进程学习总结 孤儿进程和守护进程非诚_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《linux进程学习总结 孤儿进程和守护进程非诚》由会员分享,可在线阅读,更多相关《linux进程学习总结 孤儿进程和守护进程非诚(11页珍藏版)》请在金锄头文库上搜索。

1、Linux进程学习总结孤儿进程和守护进程非诚Linux进程学习总结-孤儿进程和守护进程2011年09月23日通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程。现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程 如果一个子进程的父进程先于子进程 结束, 子进程就成为一个孤儿进程,它由 init 进程收养,成为 init 进程的子进程。 2.那么如何让一个进程变为一个孤儿进程呢? 我们可以先创建一个进程,然后杀死其父进程,则其就变成了孤儿进程。 pid = fork(); if(pid 0) exit(0); 3. 函数

2、实例: 1 #include 2 #include 3 #include 4 #include 5 6 int main() 7 8 pid_t pid; 9 pid = fork(); 10 if(!pid) 11 while(1) 12 printf(A background process,PID:%dn,ParentID:%dn ,getpid(),getppid(); 13 sleep(3); 14 15 16 17 else if(pid 0) 18 printf(I am parent process,my pid is %dn,getpid() ); 19 exit(0); 2

3、0 21 else 22 printf(Process creation failed!n); 23 24 return 0; 25 26 程序运行结果 I am parent process,my pid is 2026 A background process,PID:2027 ,ParentID:2026 thinkUbuntu:/work/process_thread/fork2$ A background process,PID:2027 ,ParentID:1 A background process,PID:2027 ,ParentID:1 A background proces

4、s,PID:2027 ,ParentID:1 A background process,PID:2027 ,ParentID:1 A background process,PID:2027 ,ParentID:1 A background process,PID:2027 ,ParentID:1 Tiger-John说明: 通过以上方法,就可以实现把一个进程变为孤儿进程 。 当要结束一个孤儿进程时只能在终端输入命令: kill 2027(kill 孤儿进程号)来结束其运行。 二守护进程 . 什么是守护进程呢? ( daemon) 是指在后台运行,没有控制终端与之相连的进程。它独立于控制终端,通

5、常周期性地执行某种任务 。 iger-John说明: 那么,守护进程为什么要脱离后台去运行呢? 守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断 . 为什么要引入守护进程: 由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。

6、 .守护进程的特性 1守护进程最重要的特性是后台运行 。 2其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是 shell )中继承下来的。 3最后,守护进程的启动方式有其特殊之处。它可以在 Linux 系统启动时从启动脚本 /etc/rc.d 中启动,可以由作业规划进程 crond 启动,还可以由用户终端(通常是 shell )执行。 4. 守护进程的启动方式有多种: a. 它可以在 Linux 系统启动时从启动脚本 /etc/rc.d 中启动 b. 可以由作业规划进程

7、 crond 启动; c. 还可以由用户终端(通常是 shell )执行。 Tiger-John 总结: 守护进程是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。 Linux 系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程 crond 、打印进程 lqd 等(这里的结尾字母 d 就是 Daemon 的意思)。 5. 如何编写守护进程呢 第一步:创建子进程,父进程退出 . 由于守护进程是脱离控制终端的,因

8、此,完成第一步后就会在 Shell 终端里造成一程序已经运行完毕的假象。之后的所有工作都在子进程中完成,而用户在 Shell 终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离。 2 在 Linux 中父进程先于子进程退出会造成子进程成为孤儿进程,而每当系统发现一个孤儿进程时就会由 1 号进程( init) 收养它。 方法是调用 fork 产生一个子进程,然后使得父进程退出 pid = fork(); if( 0 = pid) exit(0); / 如果是父进程,就结束父进程,子进程结束。 第二步:在子进程中创建新会话: 这个步骤是创建守护进程中最重要的一步,使用系统函数 setsi

9、d Tiger-John 补充: 几个相关概念 a. 进程组:是一个或多个进程的集合。进程组有进程组 ID 来唯一标识。除了进程号( PID )之外,进程组 ID ( GID) 也是一个进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组 ID 。且该进程组 ID 不会因组长进程的退出而受到影响。 b. 会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始与用户登录,终止于用户退出,在此期间该用户运行的所用进程都属于这个会话期。 c. 登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。 Tiger-John 说明: 为什么

10、要涉及它们呢? 因为控制终端,登录会话和进程组通常是从父进程继承下来的。我们就是要摆脱它们,使之不受它们的影响。 那么如何去实现呢,此时我们在第一步的基础上可以调用 setsid ()函数。 1setsid 函数用于创建一个新的会话,并担任该会话组的组长。调用 setsid 有下面的 3 个作用: 让进程摆脱原会话的控制 让进程摆脱原进程组的控制 让进程摆脱原进程组的控制 让进程摆脱原控制终端的控制 2. 在创建守护进程时为什么要调用 setsid 函数呢? 由于创建守护进程的第一步调用了 fork 函数来创建子进程,再将父进程退出。由于在调用了 fork 函数时,子进程全盘拷贝了父进程的会话

11、期,进程组,控制终端等,虽然父进程退出了,但会话期,进程组,控制终端等并没有改变,因此,还不是真正意义上的独立开来,而 setsid 函数能够使进程完全独立出来,从而摆脱其他进程的控制。 Tiger-John 说明: a. 当进程组是会话组长时 setsid() 调用失败。但是通过第一步已经保证了进程不是会话组长。 b.setsid( )调用成功后,进程成为新的会话组长和新的进程组长,并于原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 c. 此时我们还要禁止进程重新打开控制终端 进程虽然已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使

12、进程不再成为会话组长来禁止进程重新打开控制终端: 那么如何实现呢? 我们可以再次建立一个子进程,退出父进程,保证该进程不是进程组长,同时让该进程无法再打开一个新的终端 pid = fork() ; exit(0) ; 第三步:改变当前目录为根目录 1使用 fork 创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后的使用会造成很多的不便。因此,我们一般是让” /” 作为守护进程的当前工作目录,这样就可以避免上述的问题。如果有特殊需要,也可以把当前工作目录换成其他的路径。 2改变工作目录的常见函数是 chdir(). 第四步:重设文件权限掩码

13、1文件权限掩码是指屏蔽掉文件权限中的对应位。由于使用 fork 函数新建的子进程继承了父进程的文件权限掩码,这就给子进程使用文件带来了很多的麻烦。因此,把文件权限掩码设置为 0 ,可以很大程度上增强该守护进程的灵活性。 2设置文件权限掩码的函数是 umask. 通常使用的方法是 umask(0). 第五步:关闭文件描述符 1 因为用 fork 函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。 2 在上面的第二步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输入的字符不可能到

14、达守护进程,守护进程中常规方法(如 printf )输出的字符也不可能在终端上显示出来。所以,文件描述符为 0 , 1 和 2 的 3 个文件(常说的输入,输出和报错)已经失去了意义,也应该关掉。 3函数实例: for(i=0;i处理 SIGCHLD 信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程( zombie) 从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务进程的并发性能。 2函数实现: signal(SIGCHLD,SIG_IGN); 这样,内核在子进程结束时不会产生僵尸进程。 6具体函数实现: 编写一个守护进程要包括两部分:主程序 test.c 和初始化程序 init.c 。 初始化程序中的 init_daemon 函数负责生成守护进程。利用 init_daemon 函数可以生成自己的守护进程。 daemon.c 1 #includestd

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 管理学资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号