Linux系统编程2——进程介绍

news2025/1/13 15:53:12

文章目录

  • 前言
  • 一、程序和进程
  • 二、并行和并发
  • 三、进程控制块PCB
    • 进程状态
  • 四、创建进程相关函数
    • 1、fork函数
      • fork函数总结
    • 2、getpid/getppid
    • 3、exec函数族
      • 3.1、execl函数
      • 3.2、execlp函数
      • 3.3、exec函数族原理介绍
  • 五、进程回收
    • 1、为什么要进行进程资源回收
    • 2、孤儿进程
    • 3、僵尸进程
    • 4、进程回收函数
      • 4.1、wait函数
      • 4.2、waitpid函数

前言

本文用于Linux系统编程中进程相关知识。

一、程序和进程

程序,是指编译好的二进制文件,在磁盘上,占用磁盘空间, 是一个静态的概念.
进程,一个启动的程序, 进程占用的是系统资源,如:物理内存,CPU,终端等,是一个动态的概念。程序 → 剧本(纸) ,进程 → 戏(舞台、演员、灯光、道具…)
同一个剧本可以在多个舞台同时上演。同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)。

二、并行和并发

并发指的是在一个时间段内,在同一个CPU上同时运行多个程序,而并行是指两个或两个以上的程序在同一时刻发生(需要多颗CPU)。

三、进程控制块PCB

每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。
/usr/src/linux-headers-4.4.0-96/include/linux/sched.h文件的1390行处可以查看struct task_struct 结构体定义。其内部成员有很多,我们重点掌握以下部分即可:

  • 进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。

  • 进程的状态,有初始、就绪、运行、挂起、停止等状态。

  • 进程切换时需要保存和恢复的一些CPU寄存器。

  • 描述虚拟地址空间的信息。

  • 描述控制终端的信息。

  • 当前工作目录(Current Working Directory)。

    getcwd --pwd

  • umask掩码。

  • 文件描述符表,包含很多指向file结构体的指针。

  • 和信号相关的信息。

  • 用户id和组id。

  • 会话(Session)和进程组。

  • 进程可以使用的资源上限(Resource Limit)。

    ulimit -a

进程状态

进程有5种状态:初始、就绪、运行、挂起与终止。其中初始态为进程准备阶段,常与就绪态结合来看。
在这里插入图片描述

四、创建进程相关函数

1、fork函数

函数作用:创建子进程

函数原型:pid_t fork(void);
函数参数:无
返回值:
	成功:父进程返回子进程的PID,子进程返回0
	失败:返回-1,设置errno值

在这里插入图片描述

fork函数总结

fork函数的返回值?
父进程返回子进程的PID,是一个大于0数;
子进程返回0;
特别需要注意的是:不是fork函数在一个进程中返回2个值,而是在父子进程各自返回一个值。

子进程创建成功后,代码的执行位置?
父进程执行到什么位置,子进程就从哪里执行

如何区分父子进程
通过fork函数的返回值

父子进程的执行顺序
不一定,哪个进程先抢到CPU,哪个进程就先执行

2、getpid/getppid

函数原型:pid_t getpid(void);
函数作用:得到当前进程的pid

函数原型:pid_t getppid(void);
函数作用:得到当前进程父进程的PID

3、exec函数族

有的时候需要在一个进程里面执行其他的命令或者是用户自定义的应用程序,此时就用到了exec函数族当中的函数。
使用方法一般都是在父进程里面调用fork创建处子进程,然后在子进程里面调用exec函数。

3.1、execl函数

函数原型: int execl(const char *path, const char *arg, ... /* (char  *) NULL */);
参数介绍:
	path: 要执行的程序的绝对路径
	arg:占位,通常写应用程序的名字
	arg后面的: 命令的参数
	参数写完之后: NULL
返回值:
	成功,则不返回,不会再执行exec函数后面的代码;
	失败,会执行execl后面的代码,可以用perror打印错误原因。
execl函数一般执行自己写的程序。

3.2、execlp函数

函数原型: int execlp(const char *file, const char *arg, .../* (char  *) NULL */);
参数介绍:
	file: 执行命令的名字, 根据PATH环境变量来搜索该命令
	arg:占位
	arg后面的: 命令的参数
	参数写完之后: NULL
返回值:
	成功,则不返回,不会再执行exec函数后面的代码;
	失败,会执行exec后面的代码,可以用perror打印错误原因。
execlp函数一般是执行系统自带的程序或者是命令.

3.3、exec函数族原理介绍

exec族函数的实现原理图:
如:execlp(“ls”, “ls”, “-l”, NULL);
在这里插入图片描述
总结:
exec函数是用一个新程序替换了当前进程的代码段、数据段、堆和栈;原有的进程空间没有发生变化,并没有创建新的进程,进程PID没有发生变化。

//fork函数测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
	//创建子进程
	pid_t pid = fork();
	if(pid<0) //fork失败的情况
	{
		perror("fork error");
		return -1;
	}
	else if(pid>0)//父进程
	{
		printf("father: [%d], pid==[%d], fpid==[%d]\n", pid, getpid(),getppid());
		//sleep(1);
	}
	else if(pid==0) //子进程
	{
		printf("child: pid==[%d], fpid==[%d]\n", getpid(), getppid());
		//execl("/bin/ls", "ls", "-l", NULL);
		//execl("./test", "test", "hello", "world", "ni", "hao", NULL);
		execlp("ls", "ls", "-l", NULL);
	
		perror("execl error");
	}
	
	return 0;
}

五、进程回收

1、为什么要进行进程资源回收

当一个进程退出之后,进程能够回收自己的用户区的资源,但是不能回收内核空间的PCB资源,必须由它的父进程调用wait或者waitpid函数完成对子进程的回收,避免造成系统资源的浪费。

2、孤儿进程

若子进程的父进程已经死掉了,而子进程还存活着,这个进程就成了孤儿进程。为了保证每个进程都有一个父进程,孤儿进程会被init进程领养,init进程成为了孤儿进程的养父进程,当孤儿进程退出之后,由init进程完成对孤儿进程的回收。

3、僵尸进程

若子进程死了,父进程还活着,但是父进程没有调用wait或waitpid函数完成对子进程的回收,则该子进程就成了僵尸进程。
如何解决僵尸进程
由于僵尸进程是一个已经死亡的进程,所以不能使用kill命令将其杀死通过杀死其父进程的方法可以消除僵尸进程杀死其父进程后,这个僵尸进程会被init进程领养,由init进程完成对僵尸进程的回收。

4、进程回收函数

4.1、wait函数

函数原型:pid_t wait(int *status);
函数作用:
	1、阻塞并等待子进程退出
	2、回收子进程残留资源
	3、获取子进程结束状态(退出原因)
返回值:
	成功:清理掉的子进程ID;
	失败:-1 (没有子进程)
status参数:子进程的退出状态 -- 传出参数
	WIFEXITED(status):为非0 → 进程正常结束
	WEXITSTATUS(status):获取进程退出状态 
	WIFSIGNALED(status):为非0 → 进程异常终止
	WTERMSIG(status):取得进程终止的信号编号。

4.2、waitpid函数

函数原型:pid_t waitpid(pid_t pid, int *status, in options);
函数作用:同wait函数
函数参数:
	pid:
		pid = -1 等待任一子进程。与wait等效。
		pid > 0 等待其进程ID与pid相等的子进程。
		pid = 0 等待进程组ID与目前进程相同的任何子进程,也就是说任何和调用
		     waitpid()函数的进程在同一个进程组的进程。
		pid < -1 等待其组ID等于pid的绝对值的任一子进程。(适用于子进程在其他组的情况)
	status: 子进程的退出状态,用法同wait函数。
	options:设置为WNOHANG,函数非阻塞,设置为0,函数阻塞。
函数返回值
	>0:返回回收掉的子进程ID;
	-1:无子进程
	=0:参3为WNOHANG,且子进程正在运行。

//父进程调用wait函数完成对子进程的回收
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
	//创建子进程
	pid_t pid = fork();
	if(pid<0) //fork失败的情况
	{
		perror("fork error");
		return -1;
	}
	else if(pid>0)//父进程
	{
		printf("father: [%d], pid==[%d], fpid==[%d]\n", pid, getpid(),getppid());
		int status;
		pid_t wpid = wait(&status);
		printf("wpid==[%d]\n", wpid);
		if(WIFEXITED(status)) //正常退出
		{
			printf("child normal exit, status==[%d]\n", WEXITSTATUS(status));
		}
		else if(WIFSIGNALED(status)) //被信号杀死
		{
			printf("child killed by signal, signo==[%d]\n", WTERMSIG(status));
		}
		
	}
	else if(pid==0) //子进程
	{
		
		printf("child: pid==[%d], fpid==[%d]\n", getpid(), getppid());
		sleep(20);
		return 9;
	}

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

传奇GEE引擎版本架设

传奇GEE引擎版本架设 我是艾西今天给大家分享下传奇GEE引擎版本的架设教程 &#xff08;仅做参考&#xff0c;以下内容为显示素材打码部分请读者理解遵守平台GZ&#xff09; 传奇GEE引擎版本我们架设游戏需要用到的工具&#xff1a; 版本&#xff08;游戏类型服务端&#xf…

[附源码]Node.js计算机毕业设计高校学生管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

[附源码]Node.js计算机毕业设计公司疫情健康信息管理系统appExpress

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

冰刃(IceSword)的使用方法(基础篇)

冰刃是一款功能强大的杀毒辅助软件&#xff0c;深受很多杀毒高手的青睐&#xff0c;这里我介绍一下冰刃这个软件的简单使用方法&#xff0c;供大家参考。说句实话&#xff0c;我不是高手&#xff0c;不能像高手一样把一些软件运用自如&#xff0c;所以这个方法可能有很多纰漏或…

怎么去视频的水印?两分钟让你学会操作

从事视频剪辑的小伙伴&#xff0c;想必都需要先从网上查找一些视频片段&#xff0c;再将其整合成一个视频&#xff0c;但是保存下来过后&#xff0c;再打开这些视频时&#xff0c;大家应该都会发现这些视频上都带有水印&#xff0c;很影响视频的观感度&#xff0c;从而可能会降…

Redis宝典

文章目录一.概念1.1 什么是redis1.2 redis优点二.redis的存储结构2.1 结构2.2 渐进式rehash三.Redis数据类型及应用场景3.1 字符串&#xff08;string&#xff09;3.2 字符串列表&#xff08;list&#xff09;3.3 字符串集合&#xff08;set&#xff09;3.4 有序字符串集合&…

找旅馆问题

一 问题描述 有 N 家旅馆&#xff0c;每家旅馆都有位置和价格&#xff0c;有 M 个客人希望找到一家价格可接受的最近旅馆。 二 输入和输出 1 输入 每个测试用例的第 1 行都包含两个整数 N&#xff08;N ≤200000&#xff09;和 M&#xff08;M ≤20000&#xff09;&#xf…

Python之Socket编程: 轻松连接你的应用程序

前言 什么是Socket? Python 的 Socket 模块提供了一个标准的接口&#xff0c;可以让你使用网络连接来通信。 Socket 是一种网络通信技术&#xff0c;它提供了一个通用的接口来连接不同类型的网络&#xff0c;例如互联网、局域网和本地环回地址。你可以使用 Python 的 Socke…

为什么RocketMQ不使用Zookeeper作为注册中心呢?

根据CAP理论&#xff0c;同时最多只能满⾜两个点&#xff0c;而zookeeper满足的是CP&#xff0c;也就是说zookeeper并不能保证服务的可用性&#xff0c;zookeeper在进⾏选举的时候&#xff0c;整个选举的时间太⻓&#xff0c;期间整个集群都处于不可用的状态&#xff0c;而这对…

游戏网页设计成品 学校班级网页制作模板 大学生静态HTML网页源码 dreamweaver网页作业 简单网页课程成品

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

makefile编译一个工程碰到的问题(仅做为记录,没有逻辑)

一、编译选项如下 test : all$(CC) $(CXXFLAGS) -I/DecoderFFMPEGLive/ -o Test/$.o -c Test/test.cpp$(CC) $(CXXFLAGS) -o $ Test/$.o -L. -lDecoderFFMPEGLive -lpthread 报错误&#xff1a;/usr/bin/ld: cannot open output file test: Is a directory 是因为我想生成…

论文笔记CATEGORICAL REPARAMETERIZATION WITH GUMBEL-SOFTMAX

目录Gumbel-Softmax分布Gumbel-Softmax EstimatorStraight-Through (ST) Gumbel-Softmax EstimatorStraight-Through Estimator (STE)Straight-Through (ST) Gumbel-Softmax Estimator参考Gumbel-Softmax分布 Gumbel-Softmax分布是一个定义在单纯形(simplex)上的连续分布。 Gu…

项目成功的制胜法宝——有效的领导力

项目经理在开展项目的过程中&#xff0c;为了确保项目的成功且实现价值交付&#xff0c;往往会使出浑身解数、有勇有谋、甚至熟练使用“孙子兵法”。毕竟在很多情况下&#xff0c;需要“带兵打仗”的项目经理权力微弱&#xff0c;不能像“将军”那般拥有权力的加持、一呼百应。…

javaSE - 认识字符串(String class)上半部分

前言 字符串: 在C语言里面 是 没有字符串类型的&#xff01; 但是&#xff0c;在 Java 和 C 里&#xff0c;有字符串类型【String】 什么是字符串&#xff1f;什么是字符&#xff1f; 在java里面有表示字符串的类 String 使用双引号&#xff0c;且双引号中包含任意数量的字符【…

42 | iptables的使用方法

1 iptables简介 iptables是一个linux下的防火墙工具&#xff0c;能帮助我们基于规则进行网络流量控制。它可以做到&#xff0c;但不限于以下功能&#xff1a; 允许/拒绝某种协议的链接建立&#xff0c;比如TCP&#xff0c;UDP允许/拒绝 来自某个ip的访问允许/拒绝某个端口被访…

田径运动会成绩管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 模块划分&#xff1a;通知类型、通知信息、裁判信息、运动员信息、项目类型、项目信息、场地信息、项目安排、报名信息、…

深度学习目标检测:YOLOv5实现红绿灯检测(含红绿灯数据集+训练代码)

深度学习目标检测&#xff1a;YOLOv5实现红绿灯检测(含红绿灯数据集训练代码) 1. 前言 本篇博客&#xff0c;我们将手把手教你搭建一个基于YOLOv5的红绿灯目标检测项目。目前&#xff0c;基于YOLOv5s的红绿灯检测精度平均值mAP_0.50.93919&#xff0c;mAP_0.5:0.950.63967&…

_9LeetCode代码随想录算法训练营第九天-C++栈和队列

_9LeetCode代码随想录算法训练营第九天-C栈和队列 理论基础232.用栈实现队列225.用队列实现栈 基础知识 C标准库版本 HP STL 其他版本的C STL&#xff0c;一般是以HP STL为蓝本实现出来的&#xff0c;HP STL是C STL的第一个实现版本&#xff0c;而且开放源代码。P.J.Plauge…

【软件测试】测试面试,面试官其实想要的答案......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试经理 保障xxx的…

Python入门自学进阶-Web框架——29、DjangoAdmin项目应用-整表只读、自定义用户认证

一、整表只读 对于readonly_fields是对单个字段设置只读&#xff0c;现在要对整个表使用只读&#xff0c;也做成可配置的。在自己项目的admin.py中进行配置&#xff0c;如在mytestapp_admin.py中对Customer进行整表只读配置&#xff0c;在基类BaseAdmin中增加readonly_table …