一、进程组ID

每个进程都属于一个进程组。每个进程组有一个领头进程。进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号。每个进程组都有唯一的进程组ID(整数,也可以存放在pid_t类型中)。进程组由进程组ID来唯一标识。除了进程号外(PID)之外,进程组ID也是一个进程的必备属性之一。

getpgrp: 获得进程组 id, 即领头进程的 pid
#include <unistd.h>
pid_t getpgrp(void);
//返回值;调用进程的进程组ID

#include<unistd.h>
pid_t getpgid(pid_t pid);
//若成功返回进程组id,失败则返回-1.

每个进程组都有一个组长进程,组长进程的进程号等于进程组ID。组长进程可以创建一个进程组、创建该组中的进程。只要某个进程组中有一个进程存在,则该进程组就存在,与组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间成为进程组的生存期。进程组中最后一个进程可以终止或者转移到另一个进程组中。
显示子进程和父进程的组id
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main() {
pid_t pid; if ((pid=fork())<0) {
printf("fork error!");
}else if (pid==0) {
printf("The child process PID is %d.\n",getpid());
printf("The Group ID is %d.\n",getpgrp());
printf("The Group ID is %d.\n",getpgid(0));
printf("The Group ID is %d.\n",getpgid(getpid()));
exit(0);
} sleep(3);
printf("The parent process PID is %d.\n",getpid());
printf("The Group ID is %d.\n",getpgrp()); return 0;
}

程序执行的结果:

二、会话
会话是一个或多个进程组的集合。例如:


#include<unistd.h>
pid_t setsid(void);
如果调用此函数的进程不是一个进程组的组长,则此函数就会创建一个新的会话,结果发生三件事:
1、该进程变成新会话的首进程。此时,该进程是新会话中唯一的进程。
2、该进程成为一个进程组的组长进程。新的进程组ID就是调用进程的ID。
3、该进程没有控制终端。如果在调用setsid之前该进程有一个控制终端,那么这种联系也会断掉。
如果该进程已经是一个进程组的组长,则此函数返回错误。为了保证不会发生这种事情,通常先调用fork,然后使其父进程终止,而子进程则继续。因为子进程继承了父进程的组ID,而其ID是新分配,两者不可能相等,所以就保证了子进程不会是一个进程组长。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main() {
pid_t pid; if ((pid=fork())<0) {
printf("fork error!");
exit(1);
}else if (pid==0) {
printf("The child process PID is %d.\n",getpid());
printf("The Group ID of child is %d.\n",getpgid(0));
printf("The Session ID of child is %d.\n",getsid(0));
sleep(10);
setsid(); // 子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程
printf("Changed:\n");
printf("The child process PID is %d.\n",getpid());
printf("The Group ID of child is %d.\n",getpgid(0));
printf("The Session ID of child is %d.\n",getsid(0));
sleep(20);
exit(0);
}

程序执行的结果:


三、守护进程
在linux或者unix系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程。为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统。 守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断。
守护进程编程步骤
1. 创建子进程,父进程退出
•所有工作在子进程中进行
•形式上脱离了控制终端
2. 在子进程中创建新会话
•setsid()函数
•使子进程完全独立出来,脱离控制
3. 改变当前目录为根目录
•chdir()函数
•防止占用可卸载的文件系统
•也可以换成其它路径
4. 重设文件权限掩码
•umask()函数
•防止继承的文件创建屏蔽字拒绝某些权限
•增加守护进程灵活性
5. 关闭文件描述符
•继承的打开文件不会用到,浪费系统资源,无法卸载
•getdtablesize()
•返回所在进程的文件描述符表的项数,即该进程打开的文件数目



该实例首先创建了一个守护进程,然后让该守护进程每个10s在/tmp/dameon.log中写入一句话。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h> #define MAXFILE 65535
int main()
{
pid_t pc;
int i,fd,len;
char *buf="This is a Dameon\n";
len =strlen(buf);
pc=fork();
if(pc<0){
printf("error fork\n");
exit(1);
}else if(pc>0)
exit(0);
setsid();
chdir("/");
umask(0);
for(i=0;i<MAXFILE;i++)
close(i);
while(1){
if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0){
perror("open");
exit(1);
}
write(fd, buf, len+1);
close(fd);
sleep(10);
}
}

我们可以看到程序每个10s就在对应的文件中写入内容。

Linux 的进程组、会话、守护进程的更多相关文章

  1. linux 进程通信之 守护进程

    守护进程(Daemon) Daemon(精灵)进程,是linux中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的时间.一般采用以d结尾的名字.从下面的进程信息可以看出, ...

  2. linux系统编程--守护进程,会话,进程组,终端

    终端: 在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal), 进程中,控制终端是保存在PCB中的信息,而f ...

  3. linux下的守护进程及会话、进程组

    守护进程.会话.进程组网上有许多不错的资料.我也是网上搜罗了一堆,加上自己的理解.不敢说原创,只是写在这怕自己忘记罢了.才疏学浅,难免有错误,欢迎大家指正.下面这篇写很不错,大家可以去看看:http: ...

  4. Linux 进程(二):进程关系及其守护进程

    进程关系 进程组 进程组是一个或多个进程的集合.通常,它们是在同一作业中结合起来的,同一进程组中的各进程接收来自同一终端的各种信号,每个进程组有一个唯一的进程组ID.每个进程组有一个组长进程,该组长进 ...

  5. ASP.NET Core Linux下为 dotnet 创建守护进程(必备知识)

    前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 asp.net core 应用程序,本篇主要是怎么样为我们在 Linux 或者 macOs 中部署的 dotnet 程序创建一个守护进程 ...

  6. Linux中的两种守护进程stand alone和xinetd

    Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...

  7. ASP.ENT Core Linux 下 为 donet创建守护进程(转载)

    原文地址:http://www.cnblogs.com/savorboard/p/dotnetcore-supervisor.html 前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 ...

  8. Linux网络编程学习(四) -----守护进程的建立(第三章)

    本文介绍一个例程daemon_init() #include <sys/types.h> #include <signal.h> #include <unistd.h&g ...

  9. Linux进程托管与守护进程设置

    引言 在上一篇<Linux启动之旅>中,我们了解了Linux启动过程,在该过程的最后一步,init进程拉起/etc/init.d/rcN.d/目录下指定的守护进程(daemon).假若自定 ...

  10. Windows 和 Linux 上Redis的安装守护进程配置

    # Windows 和 Linux 上Redis的安装守护进程配置 Redis 简介 ​ Redis是目前最常用的非关系型数据库(NOSql)之一,常以Key-Value的形式存储.Redis读写速度 ...

随机推荐

  1. zoj 3785 What day is that day? (打表找规律)

    题目 思路:比赛的时候有想过找循环节,但是,打表打错了. 后来,看着过了挺多人,就急了, 看了一下别人的时间 耗时都挺长的,就以为不是找规律, 没想到真是找规律,不过,这个题的数据可能挺大的. AC代 ...

  2. UVa 1220 (树的最大独立集) Party at Hali-Bula

    题意: 有一棵树,选出尽可能多的节点是的两两节点不相邻,即每个节点和他的子节点只能选一个.求符合方案的最大节点数,并最优方案判断是否唯一. 分析: d(u, 0)表示以u为根的子树中,不选u节点能得到 ...

  3. UVa 10817 (状压DP + 记忆化搜索) Headmaster's Headache

    题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两 ...

  4. [swustoj 771] 奶牛农场

    奶牛农场 Description 将军有一个用栅栏围成的矩形农场和一只奶牛,在农场的一个角落放有一只矩形的箱子,有一天将军要出门,他就把奶牛用一根绳子套牢,然后将绳子的另一端绑到了那个箱子不靠栅栏的角 ...

  5. 使用AngularJS 进行Hybrid App 开发已经有一年多时间了,这里做一个总结

    一.AngularJS 初始化加载流程 1.浏览器载入HTML,然后把它解析成DOM.2.浏览器载入angular.js脚本.3.AngularJS等到DOMContentLoaded事件触发.4.A ...

  6. python - 沙盒环境 - virtualenv - 简明使用录

    1. 不讲安装,没意思 2. 使用 virtualenv ENV # 建立环境,ENV你可以随便定,看起来像是 mkdir ENV cd ENV # 进目录呗 source bin/activate ...

  7. FFmpeg介绍及参数详细说明

    FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...

  8. 2014-LAMP兄弟连视频下载地址汇总

    linux 兄弟连2014年新版Linux视频教程百度网盘下载 http://pan.baidu.com/s/1kTsjVfx http://pan.baidu.com/s/1sjJf2OX 兄弟连2 ...

  9. rpm 命令参数使用详解

    RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包 二进制包(Binary)以及源代码包(Source)两 ...

  10. 向Oracle中插入记录时,出现“Oracle.DataAccess.Client.OracleException ORA-00933 ”错误

    错误信息的弹出框