C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发005:守护进程与进程监控

文章目录

  • [1 守护进程](#1 守护进程)
    • [1.1 进程组和会话](#1.1 进程组和会话)
    • [1.2 会话的相关概念](#1.2 会话的相关概念)
    • [1.3 守护进程的概念](#1.3 守护进程的概念)
    • [1.4 守护线程的特点](#1.4 守护线程的特点)
    • [1.5 守护进程创建的基本步骤](#1.5 守护进程创建的基本步骤)
    • [1.6 本项目守护进程的实现](#1.6 本项目守护进程的实现)
  • [2 进程监控](#2 进程监控)
    • [2.1 进程监控的实现](#2.1 进程监控的实现)

1 守护进程

1.1 进程组和会话

进程除了有进程的PID之外还有一个进程组,进程组是由一个进程或者多个进程组成。通常他们与同一作业相关联可以收到同一终端的信号。

每个进程组有唯一的进程组ID,每个进程组有一个进程组组长。如何判断一个进程是不是这个进程组的组长了,通常进程组ID等于进程ID那么这个进程就是对应进程组的组长。

1.2 会话的相关概念

会话是有一个或者多个进程组组成的集合。

一个会话可以有一个终端,建立与控制终端连接的会话首进程被成为控制进程,一个会话的几个进程组可以分为前台进程后台进程,而这些进程组的控制终端相同也就是sesion id是一样的当用户使用ctr +c 产生SIGINT信号时内核会发送信号给相应前台进程组的所有进程

如果我运行一个程序我们想要把他放到后台运行我们可以在可执行程序的后面加一个&

举个例子:./test &

如果我们想要把他提到前台进程我们可以使用fg.

1.3 守护进程的概念

守护进程也叫做精灵进程,是运行在后台的一种特殊进程他独立于控制终端并且可以周期性的执行某种任务或者等待处理某些发生的事件。

守护进程是非常有用的进程,在Linux当中大多数服务器用的就是守护进程,比如Web服务器、http等,同时守护进程完成很多系统的任务。

当Linux系统启动的时候,会启动很多系统服务,这些进程服务是没有终端的。也就是说你把终端关闭了这些系统服务是不会停止,他们一直运行着他们有一个名字就叫做守护进程

我们可以使用ps ajx来查看系统中的进程

  • 参数说明:
c 复制代码
a代表不仅列出当前用户的进程并且其他用户的进程也会被列出
x表示不仅列出所有控制终端的进程也列出所有无控制终端的进程
j表示列出也作业控制相关的进程

下面我们使用ps axj来查看系统中的守护进程:

其中TTY为?号的都表示这个进程和终端没有关系。

1.4 守护线程的特点

守护进程是一种长期运行的进程,这种进程在后台运行并且不根任何控制终端关联其主要特点如下:

c 复制代码
生存周期长[不是必须]:一般是操作系统启动的时候他启动,操作系统关闭的时候他也关闭.

守护进程和终端没有关联,也就是说他们没有控制终端,所以你控制终端退出也不会导致守护进程退出.

守护进程是在后台运行不会占着终端,终端可以执行其它命令.

1.5 守护进程创建的基本步骤

  1. 设置权限掩码,调用umask(0)权限掩码不会对文件的权限有太多的影响。

  2. 父进程创建子进程,fork一个子进程(脱离终端)出来。然后父进程退出(把终端空出来不让中端卡住):固定套路。

    • 其中fork()的目的是想调用setsid()来建立新会话。目的是子进程有单独的sid,而且子进程也成为了一个新进程组的组长,同时子进程不关联任何终端。
    • 注意:调用setsid建立新会话的进程不能是进程组的组长。
  3. 由于守护进程和终端没有关系,所以我们需要将子进程的标准输入和标准输出重定向到dev/null(空设备当中去)。

    • 我们可以使用open函数打开这个空设备文件将子进程的标准输入和标准输出重定向到这个空设备对应的文件当中。
    • 黑洞确保守护进程不从键盘接收任何东西也把任何东西打印到屏幕上。

1.6 本项目守护进程的实现

  1. 判断启动参数,若为daemon则按照守护进程启动
  2. 启动守护进程时,创建子进程用于游戏业务;父进程用于接收子进程退出状态并重启子进程
c 复制代码
void daemonlize()
{
	//1 fork
	int ipid = fork();
	if (0 > ipid)
	{
		exit(-1);
	}
	if (0 < ipid)
	{
		//2 父进程退出
		exit(0);
	}
	
	//3 子进程 设置回话ID
	setsid();
	//4 子进程 设置执行路径

	//5 子进程 重定向3个文件描述到/dev/null
	int nullfd = open("/dev/null", O_RDWR);
	if (nullfd >= 0)
	{
		dup2(nullfd, 0);
		dup2(nullfd, 1);
		dup2(nullfd, 2);
		close(nullfd);
	}
}

int main()
{
	daemonlize();

	random_name.LoadFile();
	return 0;
}

2 进程监控

2.1 进程监控的实现

cpp 复制代码
//进程监控
	while (1)
	{
		int pid = fork();
		if (0 > pid) // 这里是pid小于0
		{
			exit(-1);
		}

		/*父进程等子进程退出*/
		if (0 < pid)//pid大于0,是父进程
		{
			int iStatus = 0;
			wait(&iStatus);
			if (0 == iStatus)
			{
				exit(0);
			}
		}
		/*子进程跳出循环执行游戏业务*/
		else // 否则就是子进程
		{
			break;
		}
	}
相关推荐
小易撩挨踢28 分钟前
[特殊字符] Linux 7.1 内核正式发布:距 7.0 仅 9 周,新 CPU/GPU/文件系统全面升级
linux·运维
vortex51 小时前
Linux进程权限继承研究:从setuid()到exec()与system()的行为差异
linux·服务器·系统安全·suid
信也科技布道师1 小时前
从Istio 503 NC 错误深入理解 Mesh 路由全链路原理
java·服务器·网络
云计算磊哥@1 小时前
运维开发宝典030-MySQL06数据库运维阶段总结
运维·数据库·运维开发
鼎讯信通1 小时前
性能可拓展+功能一体化 走近 TXMN-BLG1 信号模拟设备
运维·能源·信息与通信
小小小花儿1 小时前
服务器上修改个人账户权限
linux·服务器
Coisinier1 小时前
RHCE中shell脚本基础(磁盘剩余空间监控,Web 服务状态检查,curl 访问 Web 服务并返回状态)
linux·运维·服务器·前端·nginx·操作系统
lion_zjg1 小时前
Nextcloud + Collabora CODE 离线包部署安装
运维·服务器
随便做点啥2 小时前
Agent 后台 - Token工场-集群设备配置建议
服务器·经验分享
睡不醒男孩0308232 小时前
生产环境故障销账:PostgreSQL 突发连接数暴涨与死锁,如何利用 CLup 秒级定位与解锁?
运维·数据库