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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 进程的概念与exec的用法 -> 正文阅读

[系统运维]进程的概念与exec的用法

一.进程概念

1.进程与程序的差异?
未编译的程序 ----------可执行程序
程序: 一堆待执行的程序 gcc hello.c -o hello (程序是一个静态数据) 剧本

进程: 只有程序被加载到CPU中占用资源时,根据代码每行做出反应,才能形成一个真正动态的进程
(进程是一个动态的过程) 拍戏的过程

2.可执行程序 project --> ./project --> 开启一个进程

以下的几个区域的数据会直接从程序中拷贝到内存中

.init初始化段
.data和.bss数据段
.rodata常量区

3.当程序执行时,除了会分配空间之外,系统还会为你分配一个结构体目录,读取一个目录项时就会返回一个结构体指针,这个结构体用于描述这个目录项 (描述:类型,结构体大小,索引号,偏移量,文件名)

    ./project   开启一个进程  
      -->  返回一个结构体  
      struct task_struct{};

在这里插入图片描述

这个结构体用于描述这个进程 (描述:进程ID号,信号,文件,资源…)这个结构体在哪里?

/usr/src/linux-headers-3.5.0-23/include/linux/sched.h

4. 关于进程的命令

1) 查看整个Linux系统的命令 --> pstree

//所有的进程的祖先进程都是init进程 init─┬─NetworkManager───{NetworkManager}
├─accounts-daemon───{accounts-daemon}
├─acpid
├─atd
├─avahi-daemon───avahi-daemon
├─bluetoothd
├─colord───2*[{colord}]
├─console-kit-dae───64*[{console-kit-dae}]
├─cron
├─cupsd

2) 查看进程PID号 --> ps -ef (静态)
在这里插入图片描述

3)查看进程CPU占用率 --> top (动态)

CPU实时使用率在这里插入图片描述

5. 进程的状态

就绪态 TASK_RUNNING 等待CPU资源
运行态 TASK_RUNNING 占用CPU资源
暂停态 TASK_STOPPED 收到暂停信号
睡眠态
TASK_INTERRUPTIBLE 响应信号 --> 浅度睡眠 pause() --> 直到收到一个信号为止
TASK_UNINTERRUPTIBLE 不响应信号 --> 深度睡眠
僵尸态 EXIT_ZOMBIE 进程退出时,就一定会变成僵尸态,占用CPU资源
死亡态 进程退出时,如果有进程帮自己回收资源,那么就会从僵尸态变成死亡态
在这里插入图片描述

所谓CPU资源: 指的就是 struct task_struct{};

二. 进程函数接口

1.如何创建新的进程? --> fork() --> man 2 fork

NAME
fork - create a child process //在一个进程创建子进程,父子进程就会一起执行

//头文件
#include <unistd.h>

//函数原型
pid_t fork(void); --> 不需要传递任何参数

//返回值:  pid_t  进程ID号类型

成功: 父进程返回子进程PID号 子进程返回0 失败: -1

====================================================
#include <stdio.h>
#include <unistd.h>

int main()
{
	//1.程序开始执行时,只有一个进程
	printf("hello!\n");
	
	//2.产生一个子进程
	fork();
	
	//3.父子进程同时执行这条代码,至于谁先谁后
	printf("world!\n");
	
	return 0;
}
========================================================

//情况1: 父进程先执行,子进程后执行,一旦父进程结束,就会执行return 0,就会出现命令行
gec@ubuntu:/mnt/hgfs/01/code$ ./fork
hello!
gec@ubuntu:/mnt/hgfs/01/code$ world!

//情况2: 父进程后执行,子进程先执行

gec@ubuntu:/mnt/hgfs/01/code$ ./fork
hello!
world!
gec@ubuntu:/mnt/hgfs/01/code$

总结:
1)fork()之后,父子进程并发进行
2)父子进程是随机先后执行
3)PID号没有负数

2.查看自身的PID号/查看父进程的PID号

 getpid()         getppid()

getpid, getppid - get process identification //获取相应的ID号

//头文件
   #include <sys/types.h>
   #include <unistd.h>

//函数原型
   pid_t getpid(void);  --> 查看自身的ID号
   pid_t getppid(void); --> 查看当前进程的父进程ID号

返回值:
	成功:  相应的PID号
	失败:  These functions are always successful.

三. 创建前后,父子进程资源差异?

  1. 子进程继承父进程大部分资源,PID号资源不会继承。
  2. 父子进程之间的空间相互独立,互不影响
#include <stdio.h>
#include <unistd.h>

int main()
{
	int a = 100;
	
	pid_t x = fork();
	if(x > 0)
	{
		a = 50;
		printf("parent a = %d\n",a); //50
	}
	
	if(x == 0)
	{
		printf("child a = %d\n",a); //100
	}
	
	return 0;
}

四. 关于子进程中,资源回收问题。

为什么要进行资源回收? --> 释放CPU资源

进程状态
运行态: 占用CPU资源,运行程序中代码
僵尸态: 占用CPU资源,不运行程序中代码
死亡态: 不占用CPU资源

2.解决僵尸问题:

1) 当一个进程的父进程比自身先退出,系统就会指定init为继父,等待子进程退出,回收子进程的资源 2)
当父进程还在运行时,父进程主动回收子进程资源

两种情况:
1. 父进程需要持续一段时间,再进行回收,子进程很快就结束自己的任务退出了。子进程退出时,子进程会变成僵尸态,等待自己的父进程结束任务后,再帮子进程回收资源,子进程变成死亡态

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

int main()
{
	
	pid_t x = fork();
	if(x > 0)
	{
		int i;
		printf("hello,I am parent!\n");
		//2. 由于父进程还来不及监听,子进程在2到20秒这段时间内,一直都是僵尸态
		//3. 直到20秒时,父进程主动调用wait函数回收子进程资源
		for(i=0;i<20;i++)
		{
			printf("hello!\n");
			sleep(1);
		}
		
		int state;
		//wait(NULL); //父进程不关注子进程的退出状态
		wait(&state); //阻塞等待到子进程退出为止
		printf("state = %d\n",state);
	}
	
	if(x == 0)
	{
		sleep(2);
		printf("I am child!\n");
		//1.子进程马上退出,自身变成僵尸态
	}
	
	return 0;
}

2.父进程在子进程退出之前就已经在监听子进程的状态,回收子进程资源,让子进程变成死亡态。子进程退出后,变成僵尸态,马上就会被父进程回收,进入死亡态。

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

int main()
{
	pid_t x = fork();
	if(x > 0)
	{
		int state;
		printf("hello,I am parent!\n");
		//wait(NULL); //父进程不关注子进程的退出状态
		wait(&state); //阻塞等待到子进程退出为止
		printf("state = %d\n",state);
	}
	
	if(x == 0)
	{
		int i;
		for(i=0;i<5;i++)
		{
			printf("hello!\n");
			sleep(1);
		}
		exit(1);
	}
	
	return 0;
}
  1. 回收子进程资源的接口 – wait() / waitpid()
wait for process to change state

功能: 监听子进程的状态

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

   pid_t wait(int *status);

status: 监听的子进程的退出状态的指针变量

返回值:
成功:退出的子进程的PID号
失败:-1

waitpid()是针对wait()函数的封装 --> man 2 waitpid

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

pid_t waitpid(pid_t pid, int *status, int options);

pid:

< -1    : 等待这个负数的绝对值的ID号的进程
  -1    : 等待任意一个子进程    与wait()
   0    : 等待进程组中任意一个进程
>  0    : 等待指定的子进程

status: 监听的子进程的退出状态的指针变量

     options:   
     WNOHANG:   监听子进程的退出状态,但是是非阻塞,无论当时子进程有没有退出,这个函数会立即返回!   
     WUNTRACED: 监听子进程的暂停信号,阻塞   
     WCONTINUED:监听子进程的恢复信号,阻塞    
     0 :阻塞 (等价于wait())

The call wait(&status) is equivalent to: waitpid(-1, &status, 0);

4.进程的退出

#include <stdlib.h>

void exit(int status);   ---> 清洗缓冲区后,再退出

#include <unistd.h>

void _exit(int status);   ---> 不清理缓冲区,直接退出

五. exec族

NAME
execl, execlp, execle, execv, execvp, execvpe - execute a file

SYNOPSIS

#include <unistd.h>
int execl(const char *path, const char *arg,...);
int execlp(const char *file, const char *arg,...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

path: 需要执行的那个文件的绝对路径 file: 文件名 arg:
执行程序时,需要的参数列表,以NULL作为结束标志 envp: 环境变量

只要进程被exec族替换掉,在exec函数之后的代码都不会执行在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 23:03:00  更:2022-03-10 23:04:09 
 
开发: 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:35:11-

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