`
ydbc
  • 浏览: 766652 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

一、进程组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系统中守护进程的创建方法.pdf

    "Linux系统中守护进程的创建方法" Linux 系统中守护进程是指在后台运行而又无终端或登录 shell 与之相关联的进程。守护进程可以周期性地执行某种任务或等待处理某些特定的事件,是一种很有用的进程。Linux 的...

    Linux系统下守护进程编程方法

    守护进程需要从启动它的会话和进程组中分离出来,避免受到终端信号的干扰。这通常通过调用`setsid()`函数实现,但在调用前可能需要先通过`fork()`创建一个子进程,以满足`setsid()`的条件,即当前进程不是进程组的...

    编写Linux守护进程

    编写 Linux 守护进程需要了解多个概念,如子进程、进程组、会晤期、信号机制、文件、目录和控制终端等。 要编写一个 Linux 守护进程,需要遵循以下八条经验: 1. 屏蔽一些有关控制终端操作的信号,以防止守护进程...

    基于Linux守护进程的分析与实现.pdf

    守护进程必须摆脱对控制终端、会话、进程组和工作目录的依赖,以及关闭不必要的文件描述符。通常,守护进程的创建步骤包括: 1. 脱离控制终端:调用`setsid()`创建新的会话并成为会话首进程。 2. 再次`fork()`:...

    Linux守护进程的研究.pdf

    4. 单独的进程组和会话:守护进程是其所属进程组和会话中的唯一进程。 启动守护进程的方式主要有: 1. 系统引导时启动:通过系统初始化脚本(通常位于/etc/rc.d下)启动,这是基本服务程序的常见启动方式。 2. 由...

    编写Linux守护进程.pdf

    此外,守护进程还需要改变工作目录(通常为根目录`/`),设置文件创建掩码(umask),以及可能需要进行进程组和会话领导者的转换,以完全脱离控制终端。 守护进程的可靠性是其重要特征,即使在出现系统错误的情况下...

    C语言编写linux下的守护进程

    Linux下的守护进程编写指南 在 Linux 操作系统中,守护进程(Daemon)是一种特殊类型的进程,它在后台运行,独立于控制终端,用于提供特定的服务或功能。编写 Linux下的守护进程需要使用 C 语言,了解操作系统的...

    xxxx.rar_linux 守护_linux 守护进程

    在Linux操作系统中,守护进程(Daemon)是一种在后台运行且没有控制终端的程序,它们通常在系统启动时启动,负责执行特定的任务,如网络服务、日志管理等。"xxxx.rar_linux 守护_linux 守护进程"这个压缩包文件可能...

    06--Linux系统编程-守护进程、线程.pdf

    在Linux中,会话和进程组的创建和管理是系统编程中常见的任务。它们在实现进程间通信、管理和控制多个进程的执行等方面发挥着关键作用。理解这些概念有助于编写更为稳定和高效的系统软件。此外,线程的引入大大提高...

    Linux 守护进程

    2. **调用`setsid()`函数**:在第一个`fork()`之后,调用`setsid()`函数使子进程成为一个新的会话领导者,同时成为一个新的进程组领导者,这样可以确保进程独立于任何控制终端运行。 ```c setsid(); ``` 3. **...

    Linux守护进程的研究

    4. **独立的进程组和会话**:每个守护进程都是自身所属进程组和会话的唯一成员。这意味着它们与其他进程之间不存在直接的关联,有助于确保它们不受其他进程的影响。 守护进程的这些特点使得它们能够在后台安静地...

    linux守护进程

    ### Linux守护进程详解 #### 一、什么是守护进程(Daemon) 在Linux系统中,守护进程是一种后台服务程序,它们在启动后与控制终端脱离,并在后台持续运行,为用户提供服务或者执行特定的任务。守护进程是操作系统...

    Linux的守护进程简介

    守护进程的父进程通常是初始化进程init,它们不属于任何终端,且进程组和会话标识均为特殊值。 创建守护进程的关键步骤包括: 1. 清除文件创建权限:守护进程需要确保不会继承不必要的文件描述符,以避免与父进程...

    Linux守护进程的应用研究.pdf

    4. **进程组组长和会话首进程**:守护进程既是其进程组的组长进程,也是会话的首进程,并且是这些组和会话中的唯一进程。 创建守护进程通常涉及以下步骤: 1. **让init进程成为父进程**:通过fork创建子进程,并让...

    进程监视进程守护

    守护进程通常设置为后台运行,不受用户会话影响,即使用户注销或关机,它也能继续工作。 "PSZProxyMonitor"可能是这款进程监视器的名称,可能用于监控代理服务器进程或者其他特定的进程。它可能具有自定义配置功能...

    Linux以守护进程方式运行的信息服务器

    1. 变换进程组和会话:通过`fork()`函数创建子进程,然后让父进程退出,使得子进程成为孤儿进程。接着调用`setsid()`函数使进程成为新的会话组长,从而脱离原始的终端。 2. 忽略信号:守护进程通常忽略SIGHUP信号,...

    linux守护进程随系统启动而启动

    在Linux系统中,守护进程(daemon)是一种在后台运行且没有控制终端的程序,它们通常用于提供持续的服务,如Web服务器、数据库服务等。要使一个守护进程在系统启动时自动启动,需要将其配置为系统服务,并将其添加到...

Global site tag (gtag.js) - Google Analytics