IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux c/c++进程之僵尸进程和守护进程 -> 正文阅读

[系统运维]Linux c/c++进程之僵尸进程和守护进程

目录

1. 僵尸进程

1.1 僵尸进程的定义:

1.2 僵尸进程的解决办法

2.守护进程

2.1? 守护进程概念

2.2 守护进程的查看方法

2.3 守护进程的创建?

2.4 创建守护进程编程模型

2.5 进程的组织形式

2.6 守护进程的关闭

2.7 终端标准输入输出设备


1. 僵尸进程

1.1 僵尸进程的定义:

???????父进程创建了子进程,而父进程先于子进程结束,子进程的资源没有被释放,就会变成僵尸进程,持续占用系统资源

1.2 僵尸进程的解决办法

???????子进程在结束之前会向父进程发送SIGCHLD信号,父进程接收到信号之后,先回收子进程资源,然后父进程自己再结束

???????想要防止僵尸进程的情况出现,可以在父进程中写一个wait函数(或者waitpid函数)等待子进程发送的SIGCHLD信号

无wait()函数的情况:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(){
	if(fork()){
		printf("子进程被创建!\n");
	}else{
		for(int i = 0;i<5;i++){
			printf("子进程执行:%d\n",i+1);
			sleep(1);
		}
	}
	printf("父进程结束!\n\n");
	return 0;
}

?运行结果:

? ? ?从上面的输出结果可以看出,在没有wait()函数的情况下,父进程并不会等待子进程结束之后再执行"父进程结束!"这句话,如果在此时父进程在子进程未结束前被强制结束,那么就会造成僵尸进程的情况出现

?有wait()函数的情况:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(){
	if(fork()){
		printf("子进程被创建!\n");
		wait(0);
	}else{
		for(int i = 0;i<5;i++){
			printf("子进程执行:%d\n",i+1);
			sleep(1);
		}
	}
	printf("父进程结束!\n\n");
	return 0;
}

?运行结果:

?

? ? ? ?当存在wait()函数时,父进程会等待子进程发送的SIGCHLD信号,当父进程接收到信号之后,先回收子进程资源,父进程再结束

2.守护进程

2.1? 守护进程概念

独立记录其它进程的情况,记录操作系统日志等

2.2 守护进程的查看方法

?ps? -axj

TPGID为 -1 的是守护进程

??

2.3 守护进程的创建?

?2.3.1 守护进程的功能实现和其它进程一样

?2.3.2 将一个进程变为守护进程的步骤

  • 干掉其父进程
  • 摆脱终端控制(关闭0 1 2 文件描述符并重定向当前进程的io操作到 /dev/NULL (黑洞设备))
  • 摆脱原有会话,进程组的控制从而创建新的会话

2.4 创建守护进程编程模型

?2.4.1 创建守护进程方式一

  1. ?创建新会话? ? ? ? ? ? ? ? setsid()函数
  2. ?改变当前工作目录? ? ? chdir()函数
  3. ?重设当前文件权限? ? ? umask()函数
  4. ?关闭文件? ? ? ? ? ? ? ? ? ? ?close()函数

?2.4.2 创建守护进程方式二

  1. ? 重设文件权限? ? ? ? ? ? ? ? ? ? ? ? ? umask()函数
  2. ? 创建子进程? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fork()函数
  3. ? 结束父进程? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
  4. ? 创建新会话? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setsid()
  5. ? 防止子进程成为僵尸进程? ? ? ? ?signal()函数忽略掉SIGCHLD? SIGHUP信号
  6. ? 改变当前工作目录? ? ? ? ? ? ? ? ? ? ?chdir()函数
  7. ? 重定向文件描述符号? ? ? ? ? ? ? ? ?open()函数? ? dup2()函数
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(){
	// 1. 重设文件权限
	umask(0);
	// 2. 创建子进程
	int ret = fork();
	if(ret < 0) printf("创建进程失败:%m"),exit(-1);
	if(ret > 0) printf("父进程结束:%m\n"),exit(0); 	// 3. 让父进程结束
	if(0 == ret){
		printf("pid:%d\n",getpid());
		// 4. 创建新会话
		setsid();
		// 5. 防止子进程成为僵尸进程   忽略掉SIGCHLD SIGHUP信号
		signal(SIGCHLD,SIG_IGN);
		signal(SIGHUP,SIG_IGN);
		// 6. 改变当前工作目录
		chdir("/");
		// 7. 重定向文件描述符号
		int fd = open("/dev/NULL",O_RDWR);
		dup2(fd,0);
		dup2(fd,1);
	}
	
	while(1){
		//做事情(模拟守护进程工作)
		sleep(1);
	}

	return 0;
}

结果:?

?关闭守护进程:

?由此可知上方创建的pid为3469的守护进程已经被关闭

2.5 进程的组织形式

?多个进程组成一个进程组

?多个进程组组成一个会话

?注: 进程组的组长 session进程

?2.6 守护进程的关闭

?直接使用kill 2 pid 将指定进程干掉即可

?2.7 终端标准输入输出设备

  • ?0? ? 标准输入设备
  • ?1? ? 标准输出设备
  • ?2? ? 标准错误输出设备
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:35:20  更:2022-03-06 13:35:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 3:17:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码