0.预备知识
- **前台进程:**和终端关联的进程
- 任何一次会话,只允许有一个前台进程和多个后台进程
- 守护进程不能直接向显示器打印消息,一旦打印,会被暂停、终止
- 守护进程也叫做精灵进程,是特殊的孤儿进程
- 它不但运行在后台,最主要的是脱离了与终端和登录会话的所有联系
- 守护进程是非常有用的进程,在Linux当中大多数服务器用的就是守护进程,比如Web服务器http等
- 一般对外提供服务的服务器,都是以守护进程的方式工作的,一旦启动之后,除非用户主动关闭,否则,一直会在运行
2.进程组概念
- 进程除了有自己的PID、PPID,还有一个PGID(组ID)
- 进程组是由一个进程或者多个进程组成,通常它们与同一作业相关联,可以收到同一终端的信号
- 每个进程组有一个进程组组长,组长一般是第一个进程
- 如何判断一个进程是不是这个进程组的组长?
- 进程组ID = 进程ID --> 此进程就是对应进程组组长
3.会话概念
- 任何一次登录,登陆的用户,需要有多个进程(组)来给这个用户提供服务的,用户可以自己启动很多进程(组)
- 把给用户提供服务的进程或者用户自己启动的所有的进程或者服务,整体都是要属于一个叫做会话的机制中的
- 如何将自己变成自成会话呢?
- 系统调用**setsid()**
- **setsid()**要被成功调用,必须保证当前进程不是进程组组长
- 如何保证自己不是组长?
- 系统调用daemon()
- 原型:
int daemon(int nochdir, int noclose);
- 参数:
- **nochdir:**若为0,则将守护进程的工作目录改为根目录,否则不做处理
- noclose:若为0,则将守护进程的标准输入、标准输出、标准错误重定向到/dev/null,否则不做处理
- 自己实现一个daemon()
- nohup命令
void Daemon()
{signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);if(fork() > 0){exit(0);}setsid();int devnull = open("/dev/null", O_RDONLY | O_WRONLY);if(devnull > 0){dup2(0, devnull);dup2(1, devnull);dup2(2, devnull);close(devnull);}
}
- 说明:/dev/null是一个字符文件(设备),类似于Linux下的一个"文件黑洞" or"垃圾桶",通常用于屏蔽/丢弃输入输出信息