当前位置首页 > Linux知识

Linux--进程组、会话、守护进程

阅读次数:289 次  来源:admin  发布时间:

进程组   一个或多个进程的集合   进程组ID: 正整数   两个函数   getpgid(0)=getpgrp()

Linux--进程组、会话、守护进程

eg:显示子进程与父进程的进程组id

 1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <unistd.h>

4

5 int main() {

6 pid_t pid

7

8 if ((pid=fork())<0) {

9 printf("fork error!")

10 }else if (pid==0) {

11 printf("The child process PID is %d.\n",getpid())

12 printf("The Group ID is %d.\n",getpgrp())

13 printf("The Group ID is %d.\n",getpgid(0))

14 printf("The Group ID is %d.\n",getpgid(getpid()))

15 exit(0)

16 }

17

18 sleep(3)

19 printf("The parent process PID is %d.\n",getpid())

20 printf("The Group ID is %d.\n",getpgrp())

21

22 return 0

23 }

Linux--进程组、会话、守护进程

进程组id = 父进程id,即父进程为组长进程

组长进程   组长进程标识: 其进程组ID==其进程ID   组长进程可以创建一个进程组,创建该进程组中的进程,然后终止   只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关   进程组生存期: 进程组创建到最后一个进程离开(终止或转移到另一个进程组) 一个进程可以为自己或子进程设置进程组ID   setpgid()加入一个现有的进程组或创建一个新进程组

Linux--进程组、会话、守护进程

eg:父进程改变自身和子进程的组id

 1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <unistd.h>

4

5 int main() {

6 pid_t pid

7

8 if ((pid=fork())<0) {

9 printf("fork error!")

10 exit(1)

11 }else if (pid==0) {

12 printf("The child process PID is %d.\n",getpid())

13 printf("The Group ID of child is %d.\n",getpgid(0)); // 返回组id

14 sleep(5)

15 printf("The Group ID of child is changed to %d.\n",getpgid(0))

16 exit(0)

17 }

18

19 sleep(1)

20 setpgid(pid,pid); // 改变子进程的组id为子进程本身

21

22 sleep(5)

23 printf("The parent process PID is %d.\n",getpid())

24 printf("The parent of parent process PID is %d.\n",getppid())

25 printf("The Group ID of parent is %d.\n",getpgid(0))

26 setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程

27 printf("The Group ID of parent is changed to %d.\n",getpgid(0))

28

29 return 0

30 }

Linux--进程组、会话、守护进程

会话: 一个或多个进程组的集合   开始于用户登录   终止与用户退出   此期间所有进程都属于这个会话期

Linux--进程组、会话、守护进程

建立新会话:setsid()函数   该调用进程是组长进程,则出错返回     先调用fork, 父进程终止,子进程调用   该调用进程不是组长进程,则创建一个新会话     •该进程变成新会话首进程(session header)     •该进程成为一个新进程组的组长进程。     •该进程没有控制终端,如果之前有,则会被中断 组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程...

Linux--进程组、会话、守护进程

会话ID:会话首进程的进程组ID 获取会话ID: getsid()函数

Linux--进程组、会话、守护进程

 1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <unistd.h>

4

5 int main() {

6 pid_t pid

7

8 if ((pid=fork())<0) {

9 printf("fork error!")

10 exit(1)

11 }else if (pid==0) {

12 printf("The child process PID is %d.\n",getpid())

13 printf("The Group ID of child is %d.\n",getpgid(0))

14 printf("The Session ID of child is %d.\n",getsid(0))

15 sleep(10)

16 setsid(); // 子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程

17 printf("Changed:\n")

18 printf("The child process PID is %d.\n",getpid())

19 printf("The Group ID of child is %d.\n",getpgid(0))

20 printf("The Session ID of child is %d.\n",getsid(0))

21 sleep(20)

22 exit(0)

23 }

24

25 return 0

26 }

Linux--进程组、会话、守护进程

在子进程中调用setsid()后,子进程成为新会话首进程,且成为一个组长进程,其进程组id等于会话id

守护进程   Linux大多数服务都是通过守护进程实现的,完成许多系统任务   0: 调度进程,称为交换进程(swapper),内核一部分,系统进程   1: init进程, 内核调用,负责内核启动后启动Linux系统   没有终端限制   让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进程变成一个守护进程 守护进程编程步骤   1. 创建子进程,父进程退出     •所有工作在子进程中进行     •形式上脱离了控制终端   2. 在子进程中创建新会话     •setsid()函数     •使子进程完全独立出来,脱离控制   3. 改变当前目录为根目录     •chdir()函数     •防止占用可卸载的文件系统     •也可以换成其它路径   4. 重设文件权限掩码     •umask()函数     •防止继承的文件创建屏蔽字拒绝某些权限     •增加守护进程灵活性   5. 关闭文件描述符     •继承的打开文件不会用到,浪费系统资源,无法卸载     •getdtablesize()     •返回所在进程的文件描述符表的项数,即该进程打开的文件数目

Linux--进程组、会话、守护进程

 1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <unistd.h>

5 #include <sys/wait.h>

6 #include <sys/types.h>

7 #include <fcntl.h>

8

9 int main() {

10 pid_t pid

11 int i,fd

12 char *buf="This is a daemon program.\n"

13

14 if ((pid=fork())<0) {

15 printf("fork error!")

16 exit(1)

17 }else if (pid>0) // fork且退出父进程

18 exit(0)

19

20 setsid(); // 在子进程中创建新会话。

21 chdir("/"); // 设置工作目录为根

22 umask(0); // 设置权限掩码

23 for(i=0;i<getdtablesize();i++) //getdtablesize返回子进程文件描述符表的项数

24 close(i); // 关闭这些不将用到的文件描述符

25

26 while(1) {// 死循环表征它将一直运行

27 // 以读写方式打开"/tmp/daemon.log",返回的文件描述符赋给fd

28 if ((fd=open("/tmp/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0) {

29 printf("Open file error!\n")

30 exit(1)

31 }

32 // 将buf写到fd中

33 write(fd,buf,strlen(buf)+1)

34 close(fd)

35 sleep(10)

36 printf("Never output!\n")

37 }

38

39 return 0

40 }

因为stdout被关掉了,所以“Never ouput!”不会输出。

查看/tmp/daemon.log,说明该程序一直在运行

Linux--进程组、会话、守护进程

上一篇:Nginx作为web服务器
下一篇:Fedora1764bit安装ORACLE11gR2