您的位置:首页 > 理论基础 > 计算机网络

Linux--进程组、会话、守护进程 http://www.cnblogs.com/forstudy/archive/2012/04/03/2427683.html

2015-10-03 15:07 696 查看


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

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



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 }






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

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

一个进程可以为自己或子进程设置进程组ID
  setpgid()加入一个现有的进程组或创建一个新进程组



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 }






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



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



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





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 }






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

守护进程
  Linux大多数服务都是通过守护进程实现的,完成许多系统任务
  0: 调度进程,称为交换进程(swapper),内核一部分,系统进程
  1: init进程, 内核调用,负责内核启动后启动Linux系统
  没有终端限制
  让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进程变成一个守护进程

守护进程编程步骤
  1. 创建子进程,父进程退出
    •所有工作在子进程中进行
    •形式上脱离了控制终端

  2. 在子进程中创建新会话
    •setsid()函数
    •使子进程完全独立出来,脱离控制

  3. 改变当前目录为根目录
    •chdir()函数
    •防止占用可卸载的文件系统
    •也可以换成其它路径

  4. 重设文件权限掩码
    •umask()函数
    •防止继承的文件创建屏蔽字拒绝某些权限
    •增加守护进程灵活性

  5. 关闭文件描述符
    •继承的打开文件不会用到,浪费系统资源,无法卸载
    •getdtablesize()
    •返回所在进程的文件描述符表的项数,即该进程打开的文件数目





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

绿色通道: 好文要顶 关注我 收藏该文与我联系






Alex_Monkey

关注 - 2

粉丝 - 39

+加关注

3

0

(请您对文章做出评价)

« 上一篇:JAVA数据类型基础

» 下一篇:JAVA面向对象基础

posted @ 2012-04-03 23:44 Alex_Monkey 阅读(9860)
评论(3) 编辑 收藏

评论列表

#1楼 2014-06-16
13:50 丶小圣

您好 想请问下我可以转载这篇博文到自己的博客里么
支持(0)反对(0)

#2楼 2015-05-16
13:24 放作夥

总结得真棒
支持(0)反对(0)

#3楼 2015-09-01
09:44 迷信自己的迷信

只能说非常感谢,受教了。
支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库

【推荐】免费集成极光推送SDK,让APP实现高安全、高并发的推送功能

【专享】阿里云9折优惠码:bky901

最新IT新闻:

· 微软怎么就喜欢上了仇敌Linux?

· 新华社批外卖两张皮:图片高大上 店内脏乱差

· 天涯没落:上比不了知乎 下比不了贴吧

· 苹果与运营商谈判 iPhone用户未来或无漫游费

· Facebook虚拟现实头盔起售价超过350美元

» 更多新闻...





最新知识库文章:

· HTTPS背后的加密算法

· 下一代云计算模式:Docker正掀起个性化商业革命

· 野生程序员的故事

· 状态机的两种写法

· 状态机思路在程序设计中的应用

» 更多知识库文章...

昵称:Alex_Monkey

园龄:3年10个月

粉丝:39

关注:2
+加关注

<2012年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345


搜索


常用链接

我的随笔
我的评论
我的参与
最新评论
我的标签
更多链接


我的标签

java(1)
vim(1)
框架(1)


随笔分类

Design
Pattern(4)
Hibernate(1)
Interview
Java(12)
JavaScript(2)
Linux(7)
NetworkX(3)
Polish
EffectiveJava(1)
Python(6)
Ruby(2)
SQL(1)
SVN


随笔档案

2013年10月
(1)
2013年8月
(1)
2013年5月
(3)
2013年4月
(2)
2013年3月
(1)
2013年2月
(1)
2012年10月
(2)
2012年9月
(2)
2012年6月
(3)
2012年4月
(8)
2012年3月
(15)
2011年11月
(2)


最新评论

1. Re:Linux--进程组、会话、守护进程

只能说非常感谢,受教了。

--迷信自己的迷信

2. Re:Linux--线程编程

那个有争议的代码,原本是对的,编译中会有警告,可以忽视,仍然可以生成一个执行文件,可以执行,结果也是对的。

8楼说的是错的

--我不要做程序猿

3. Re:Linux--进程组、会话、守护进程

总结得真棒

--放作夥

4. Re:Linux--线程编程

很好啊!!!感谢

--itfanr

5. Re:Linux--线程编程

不好意思啊,我上面的评论是错误的,8楼唔知叫咩名,也是错误。

--_zzy


阅读排行榜

1.
Linux--线程编程(31116)
2.
Linux--进程间通信(信号量,共享内存)(转)(10293)
3.
Linux--进程组、会话、守护进程(9860)
4.
JAVA面向对象基础(6564)
5.
networkx--四种网络模型(4375)


评论排行榜

1.
Linux--线程编程(12)
2.
Linux--进程组、会话、守护进程(3)
3.
Linux--信号编程(1)
4.
Linux--进程间通信(信号量,共享内存)(转)(1)


推荐排行榜

1.
Linux--线程编程(12)
2.
JAVA---awt(3)
3.
Linux--进程组、会话、守护进程(3)
4.
JAVA面向对象基础(1)
5.
Linux--进程间通信(信号量,共享内
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: