面试19--守护进程

本文详细介绍了守护进程(daemon)的概念,其在Linux系统中的角色,以及如何编写守护进程程序。文章解释了守护进程的特点,包括在后台运行、独立于控制终端、周期性执行任务等。此外,还提供了创建守护进程的具体步骤和示例代码,涵盖了调用fork、setsid、关闭文件描述符等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

守护进程(daemon)是指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,周期性地执行某种任务。Linux的大多数服务器就是用守护进程的方式实现的。如web服务器进程http等。守护进程在后台运行,类似于Windows中的系统服务。

  编写守护进程程序的要点:

(1)让程序在后台执行。方法是调用fork()产生一个子进程,然后使父进程退出。

(2)调用setsid()创建一个新对话期。控制终端、登录会话和进程组通常是从父进程继承下来的,守护进程要摆脱它们,不受它们的影响,方法是调用setsid()使进程成为一个会话组长。setsid()调用成功后,进程成为新的会话组长和进程组长,并与原来的登录会话、进程组和控制终端脱离。

(3)禁止进程重新打开控制终端。经过以上步骤,进程已经成为一个无终端的会话组长,但是它可以重新申请打开一个终端。为了避免这种情况发生,可以通过使进程不再是会话组长来实现。再一次通过fork()创建新的子进程,使调用fork的进程退出。

(4)关闭不再需要的文件描述符。子进程从父进程继承打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。首先获得最高文件描述符值,然后用一个循环程序,关闭0到最高文件描述符值的所有文件描述符。

(5)将当前目录更改为根目录。

(6)子进程从父进程继承的文件创建屏蔽字可能会拒绝某些许可权。为防止这一点,使用unmask(0)将屏蔽字清零。

(7)处理SIGCHLD信号。对于服务器进程,在请求到来时往往生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie),从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。这样,子进程结束时不会产生僵尸进程。

  守护进程的实例:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <time.h>
#include <syslog.h>
 
int init_daemon(void) 
{ 
	int pid; 
	int i; 
 
	//忽略终端I/O信号,STOP信号
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGTSTP,SIG_IGN);
	signal(SIGHUP,SIG_IGN);
	
	pid = fork();
	if(pid > 0) {
		exit(0); //结束父进程,使得子进程成为后台进程
	}
	else if(pid < 0) { 
		return -1;
	}
 
	//建立一个新的进程组,在这个新的进程组中,子进程成为这个进程组的首进程,以使该进程脱离所有终端
	setsid();
 
	//再次新建一个子进程,退出父进程,保证该进程不是进程组长,同时让该进程无法再打开一个新的终端
	pid=fork();
	if( pid > 0) {
		exit(0);
	}
	else if( pid< 0) {
		return -1;
	}
 
	//关闭所有从父进程继承的不再需要的文件描述符
	for(i=0;i< NOFILE;close(i++));
 
	//改变工作目录,使得进程不与任何文件系统联系
	chdir("/");
 
	//将文件当时创建屏蔽字设置为0
	umask(0);
 
	//忽略SIGCHLD信号
	signal(SIGCHLD,SIG_IGN); 
	
	return 0;
}
 
int main() 
{ 
	time_t now;
	init_daemon();
	syslog(LOG_USER|LOG_INFO,"TestDaemonProcess! \n");
	while(1) { 
		sleep(8);
		time(&now); 
		syslog(LOG_USER|LOG_INFO,"SystemTime: \t%s\t\t\n",ctime(&now));
	} 
}

  编译运行上述程序。然后用ps -ef 命令查看进程状态,该进程状态如下:





  

  从结果可以看出该进程具备守护进程的所有特征。



  查看/var/log目录下,先前并不存在的test.log文件已经有了。







  用vi打开该日志文件,记录如下:



  最后需要关闭此守护进程。关闭的方法是通过ps -ef命令查询到该进程的进程号,之后再用kill 命令将其杀死。




  注意:使用syslog函数前需要配置。但需要注意的是,在Centos6.x系统中,系统日志的配置文件已经发生了变化。不再是原来的/etc/syslog.conf了,而是/etc/rsyslog.conf。打开上述文件,在文件末尾加入下面一行:

user.* /var/log/test.log

然后重启syslog服务。重启的命令也修改为:/etc/init.d/rsyslog restart
实际上,Linux提供了完成上述同样功能的库函数:

#include <unistd.h>
int daemon(int nochdir,int noclose);

  其中,nochdir参数用于指定是否改变工作目录,如果给它传递0,则工作目录将被设置为“/”(根目录),否则继续使用当前工作目录。noclose参数为0时,标准输入、标准输出和标准错误输出都被重定向到/dev
<think>好的,我现在需要处理用户关于Linux进程管理的面试问题总结请求。首先,用户提供了三个引用内容,我需要仔细查看这些引用,提取相关信息,并组织成结构清晰的回答。 首先看引用[1],里提到了ps命令的各种参数,比如a、X、f、e、l、u等,还有排序进程的方法。这些是进程查看和监控的基础知识点,必须包含在回答中。另外,用户可能关心如何根据CPU或内存使用排序进程,这在面试中常见。 接下来是引用[3],关于僵尸进程的形成原因和解决方法。这部分内容需要详细解释,因为僵尸进程是面试中的高频问题。需要说明僵尸进程的定义,父进程如何处理,以及如何避免或清理僵尸进程。 虽然引用[2]主要关于Linux目录结构,但可能与进程管理关联不大,不过还是要注意是否有相关内容。比如,是否有进程相关的配置文件存放在/etc目录下,或者日志在/var目录下,但用户的问题集中在进程管理,所以可能不需要深入这部分。 用户的需求是获取面试相关的知识点总结,所以需要分点整理,结构清晰。常见的面试问题可能包括进程状态、查看和管理进程的命令、前后台进程切换、僵尸进程和孤儿进程的区别、进程间通信方式等。 需要确保覆盖以下内容: 1. 进程基本概念:状态、PID、PPID等。 2. 常用命令:ps、top、htop、kill、pkill、pgrep、jobs、bg/fg。 3. 进程优先级和nice值调整。 4. 僵尸进程和孤儿进程的处理。 5. 进程间通信(IPC)方法。 6. 守护进程的概念和创建。 7. 性能监控工具如vmstat、iostat等,虽然用户没提到,但可能相关。 需要结合引用[1]中的ps参数示例,比如ps aux、ps -ef,以及排序命令ps aux --sort=%mem或%cpu。同时,引用[3]中的僵尸进程需要详细说明,包括如何检测和解决,比如通过wait调用或终止父进程。 另外,用户提供的引用中有关于ps命令的参数,可能需要解释每个参数的作用,例如a显示所有进程,u显示用户信息,f显示进程树等。这些参数在面试中常被问到,需要正确解释。 可能还需要补充一些用户引用中没有提到的内容,例如top命令的交互操作(如按P按内存排序)、信号的使用(如kill -9、SIGTERM等),以及进程的前后台切换(&、jobs、fg、bg)。 需要确保回答结构清晰,分点列出,每个部分有重点,并适当举例。例如,在解释ps命令时,给出常用组合命令;在讲解僵尸进程时,说明如何通过ps查看僵尸状态(Z状态)等。 最后,生成相关问题时要围绕进程管理的常见面试问题,比如进程状态转换、命令使用场景、问题排查方法等。</think>### Linux进程管理面试知识点总结 #### 一、基础概念 1. **进程状态** Linux进程状态包括:运行中(R)、可中断睡眠(S)、不可中断睡眠(D)、僵尸(Z)、停止(T)等[^3]。 可通过`ps aux`查看进程状态,例如僵尸进程会标记为`Z`。 2. **PID与PPID** - 每个进程有唯一**进程ID(PID)**,父进程ID为**PPID**。 - 使用`ps -ef`查看进程父子关系,`pstree`以树状图显示层级。 --- #### 二、进程管理命令 1. **查看进程** - `ps`命令常用组合: - `ps aux`:显示所有进程的详细信息(用户、CPU/内存占用等)[^1] - `ps -ef`:显示完整格式的进程列表 - `ps -eLf`:查看线程信息 - 按资源排序: ```bash ps aux --sort=-%cpu # 按CPU降序 ps aux --sort=%mem # 按内存升序 ``` 2. **动态监控** - `top`:实时查看系统资源占用,支持交互操作(按`P`/`M`排序CPU/内存) - `htop`(增强版):支持颜色高亮和鼠标操作 3. **进程终止** - `kill -9 PID`:强制终止进程(发送SIGKILL信号) - `pkill -f "进程名"`:根据名称批量终止进程 --- #### 三、进程调度与控制 1. **前台/后台切换** - `&`:后台运行程序(如`python script.py &`) - `jobs`:查看后台任务列表 - `fg %n`:将后台任务n切换到前台 - `bg %n`:恢复暂停的后台任务 2. **优先级调整** - `nice -n 值 命令`:启动时设置优先级(范围-20~19,值越小优先级越高) - `renice -n 值 -p PID`:修改运行中进程的优先级 --- #### 四、僵尸进程与孤儿进程 1. **僵尸进程(Zombie)** - **成因**:子进程退出后,父进程未调用`wait()`回收其资源[^3]。 - **检测**:`ps aux | grep 'Z'` - **解决**:终止父进程(僵尸进程会由init进程接管并清理) 2. **孤儿进程** - 父进程先于子进程退出,子进程由init进程(PID=1)接管,不会造成资源泄漏。 --- #### 五、高级话题 1. **进程间通信(IPC)** 常见方式:管道(`|`)、信号(如`kill`)、共享内存、消息队列、Socket。 2. **守护进程(Daemon)** - 特点:脱离终端长期运行(如httpd、mysqld) - 创建步骤:`fork()`子进程 → 脱离会话组`setsid()` → 修改工作目录`chdir("/")` 3. **性能分析工具** - `vmstat`:监控系统整体资源(CPU、内存、IO) - `strace`:跟踪进程系统调用 - `lsof -p PID`:查看进程打开的文件描述符 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值