操作系统:进程(一)

进程的基本概念

一般的解释是:进程是程序的一个执行实例,是正在执行的程序。我们写的程序编译后是一段二进制的文件。启动的时候加载到系统里面执行,就是以进程的形式执行。也就是说,我们编译后的可执行程序是一个静态的概念,加载到系统中以进程的方式执行,是一个动态的概念。
从系统的角度看:进程是系统资源(cpu 时间,内存)分配的最小实体单位。

进程ID(PID)

每一个进程都有唯一的一个非负整数的ID,这个ID就是PID(process iD)

  • Getpid() :返回当前进程的ID
  • Getppid() : 返回当前进程的父进程的ID。
#include <unistd.h>
#include <sys/types.h>
pid_t getpid(void);
pid_t getppid(void);

父进程和子进程

这里涉及到父进程和子进程的概念。为什么会有父进程和子进程?进程的创建并不像结构体或者类一样,new一下就可以创建出来。进程之前存在着继承的关系。进程B继承于进程A,那么进程A就是进程B的父进程。进程B就是进程A的子进程。
因为进程是系统资源的分配实体,所以进程里面会有很多的系统信息,进程相关的分配的内存,寄存器,数据,PCB等很多的域。如果我们自己创建会是一个很繁琐的过程。在早期的操作系统设计的时候,就会考虑如何方便的创建进程。一个比较方便的办法就是把已经存在的进程的各个域完全拷贝一份,然后再修改不同的地方,就形成了一个新的进程,这样的话,创建的进程和被创建的进程之间就存在继承的关系,也就是父子进程。
在linux操作系统启动的时候,系统会先创建一个Init进程,这个是整个系统中的第一个进程,然后再由这个init进程去创建后面的系统进程和用户进程。所以从这个角度看,一个系统中的所有进程都有一个共同的祖先就是init进程。
父进程和子进程之间不只是复制一份的关系。父进程还需要负责子进程的资源的回收。也就是子进程结束后,有很多资源如果没有人回收的话,一个是会造成资源的浪费,另一个是时间久了,会导致整个系统没有可用的资源了。当前也会存在父进程比子进程先结束的情况,这种时候,init进程就会变成子进程的父进程。对资源进行回收,不过这个时间就会比较长。所以在编程的时候,大家还是最好自己创建的进程在使用完后就行回收,避免资源浪费。

进程退出

  • exit(status)
    这个函数没有返回值,会通过参数指定返回状态,这个返回状态会被父进程接收到,父进程就可以做一些处理。
#include<stdlib.h>
void exit(int status);

如何创建和初始化进程

上面在讲父进程和子进程的时候也提到了,如果先创建一个空的数据结构,再填充每个数据域,工作量是非常大的。所以操作系统采用的方式是通过父进程复制的方式创建新的进程。内核init进程是所有进程的祖先,pid=1, 所以的进程最初都是由init进程复制的方式而来的。
下面是创建新进程的时候用到的两个函数:

  • fork()
    通过fork()函数来创建新的进程(子进程),也就是通过这个函数去执行从父进程到子进程的复制工作。
    这个函数比较特殊的地方是,调用一个,有两个返回结果。
    1. 父进程返回创建的子进程的PID
    2. 子进程返回0
  • exec(…)
    通过上面的函数单纯的进行复制,并没有太大的意义,更多的时候我们还是希望新的进程可以执行新的任务,所以需要exec()这个函数.参数传进来一个program,更换当前的code和data,然后执行传进来的program命令。
#include <unistd.h>
#include <sys/types.h>
//Returns: 0 to child, Pid of child to parent, -1 on error
pid_t fork(void);

需要注意的是通过fork()创建的新的子进程,几乎,但不是完全的与父进程相同。父进程和子进程有不同的PID。
子进程得到一份父进程用户层虚拟机地址空间的完全拷贝。同时也得到父进程已打开的文件描述符的完全拷贝,这意味着子进程可以直接读写父进程中已经打开的任何文件。
下面是一个简单的例子:

1 #include "csapp.h"
2 #include <unistd.h>
3 int main()
4 {
5 		pid_t pid;
6 		int x = 1;
7
8 		pid = fork();
9 		if (pid == 0) { /* child */
10 		   printf("child : x=%d\n", ++x);
11 		  exit(0);
12      }
13
14 	/* parent */
15 	printf("parent: x=%d\n", --x);
16 	exit(0);
17 }

第8行调用fork()函数时,进程就产生了分差,变成了一个父进程一个子进程同时在系统中运行,在父进程中,fork()函数返回子进程的pid, 在子进程中,fork()函数返回0,表示当前是子进程自己。由于x的定义是在fork()之前,所以在执行fork()的时候,x被复制了一份,一个属于子进程,一个属于父进程。
在第10行的打印,是子进程打印的,x为2;第15行为父进程打印的为0.也就是说从fork往后,父进程和子进程的数据就是独立的两份了,相互没有了关系。

再举例如下:

1 #include "csapp.h"
2
3 int main()
4 {
5 		Fork();
6 		Fork();
7 		printf("hello!\n");
8 		exit(0);
9 }

经过第5行的fork(),就会产生一对父子进程,两个进程继续向下走,到第6行,再次fork(),两个进程又分别创建一个子进程。如下图,到第七行打印的时候就有4个进程在打印。所以使用fork()创建进程是一种指数的增长。
在这里插入图片描述

进程的并行

在操作系统中进程是并行运行的,即使是父子进程,从创建出子进程的一刻开始,两个进程就开始并行运行了。所以基于上面的程序虽然会打印4次hello.但我们无法判断是哪个进程先打印,哪个进程后打印的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ STL之string初始

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

JSP基本表单和Request对象使用例子

表单的jsp&#xff1b; <%page contentType"text/html;charsetgbk" pageEncoding"UTF-8"%> <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><titl…

golang学习笔记——接口interfaces

文章目录 Go 语言接口例子空接口空接口的定义空接口的应用空接口作为函数的参数空接口作为map的值 类型断言接口值 类型断言例子001类型断言例子002 Go 语言接口 接口&#xff08;interface&#xff09;定义了一个对象的行为规范&#xff0c;只定义规范不实现&#xff0c;由具…

数据库大事记

数据库分类分类方法为&#xff1a;按数据模型分类、按业务类型分类、按部署方式分类、按存储介质分类。 按数据模型分类 按业务类型分类 按部署方式分类 按存储介质分类 喜欢点赞收藏&#xff0c;下期再见。

【Redux】Redux 基本使用

1. Redux 快速上手 Redux 是 React 最常用的集中状态管理工具&#xff0c;类似于Vue中的Pinia&#xff08;Vuex&#xff09;&#xff0c;可以独立于框架运行。 <button id"decrement">-</button> <span id"count">0</span> <…

多线程Thread(初阶一:认识线程)

目录 一、引用线程的原因 二、线程的概念 三、进程和线程的区别 四、多线程编程 一、引用线程的原因 多任务操作系统&#xff0c;希望系统能同时运行多个任务。所以会涉及到进程&#xff0c;需要对进程进行管理、调度等。 而单任务操作系统&#xff0c;就完全不涉及到进程…

YOLOv8-Seg改进策略:全新的聚焦式线性注意力模块Focused Linear Attention | ICCV2023

🚀🚀🚀本文改进:深入分析了现有线性注意力方法的缺陷,并提出了一个全新的聚焦的线性注意力模块(Focused Linear Attention),同时具有高效性和很强的模型表达能力。 🚀🚀🚀YOLOv8-seg创新专栏:http://t.csdnimg.cn/KLSdv 学姐带你学习YOLOv8,从入门到创新,…

深度学习系列53:mmdetection上手

1. 安装 使用openmim安装&#xff1a; pip install -U openmim mim install "mmengine>0.7.0" mim install "mmcv>2.0.0rc4"2. 测试案例 下载代码和模型&#xff1a; git clone https://github.com/open-mmlab/mmdetection.git mkdir ./checkpoi…

2023年【熔化焊接与热切割】考试试卷及熔化焊接与热切割试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试试卷考前必练&#xff01;安全生产模拟考试一点通每个月更新熔化焊接与热切割试题及解析题目及答案&#xff01;多做几遍&#xff0c;其实通过熔化焊接与热切割模拟考试很简单。 1、【单选题】 对…

React+后端实现导出Excle表格的功能

最近在做一个基于Reactantd前端框架的Excel导出功能&#xff0c;我主要在后端做了处理&#xff0c;这个功能完成后&#xff0c;便总结成一篇技术分享文章&#xff0c;感兴趣的小伙伴可以参考该分享来做导出excle表格功能&#xff0c;以下步骤同样适用于vue框架&#xff0c;或者…

“轻松实现文件夹批量重命名:使用顺序编号批量改名“

你是否曾经遇到过需要批量重命名文件夹&#xff0c;却因为繁琐的手动操作而感到困扰&#xff1f;现在&#xff0c;我们为你带来了一款全新的工具——轻松实现文件夹批量重命名&#xff0c;使用顺序编号批量改名。这款工具将帮助你轻松解决文件夹重命名的问题&#xff0c;提高工…

SpringSecurity5|12.实现RememberMe 及 实现原理分析

security/day08 这个功能大家还熟悉么&#xff1f;我们在登录网站的时候&#xff0c;除了让你输入用户名和密码&#xff0c;还会有个勾选框&#xff1a; 记住我&#xff01;&#xff01;&#xff01;不是让大家记住我哈。 值得一提的是&#xff0c;Spring Security 也提供了这个…

2023年汉字小达人市级比赛在线模拟题更新:40分钟150题完整对标

今天是2023年11月19日&#xff0c;距离11月30日的汉字小达人市级比赛还有11天。许多孩子正在利用难得的周末抓紧练习和备赛。 结合一些孩子的反馈和需求&#xff0c;我把150题的在线模拟题做了更新&#xff0c;增加了前面的个人信息填写的部分&#xff0c;并且把整个试卷的完成…

python自动化标注工具+自定义目标P图替换+深度学习大模型(代码+教程+告别手动标注)

省流建议 本文针对以下需求&#xff1a; 想自动化标注一些目标不再想使用yolo想在目标检测/语意分割有所建树计算机视觉项目想玩一玩大模型了解自动化工具了解最前沿模型自定义目标P图替换… 确定好需求&#xff0c;那么我们发车&#xff01; 实现功能与结果 该模型将首先…

python——第九天

今日目标&#xff1a; 偏函数 递归 字符串对象 切片 常见排序和查找 偏函数&#xff1a; python中存在一种函数的特殊使用&#xff0c;称为偏函数 如果在调用某个函数时&#xff0c;恰好某一个或者&#xff0c;某一些参数都是一个固定值&#xff08;正好不是默认值&#xff09;…

Linux常用命令——bye命令

在线Linux命令查询工具 bye 命令用于中断FTP连线并结束程序。。 补充说明 bye命令在ftp模式下&#xff0c;输入bye即可中断目前的连线作业&#xff0c;并结束ftp的执行。 语法 bye实例 bye在线Linux命令查询工具

从0开始学习JavaScript--JavaScript 数字与日期

JavaScript中的数字和日期是处理数值计算和时间相关任务的核心。本文将深入研究JavaScript中数字的表示、常见运算&#xff0c;以及日期对象的创建、格式化等操作&#xff0c;并通过丰富的示例代码&#xff0c;可以更全面地了解和应用这些概念。 JavaScript数字基础 JavaScri…

【RocketMq系列-01】RocketMq安装和基本概念

RocketMq系列整体栏目 内容链接地址【一】RocketMq安装和基本概念https://zhenghuisheng.blog.csdn.net/article/details/134486709 RocketMq安装和基本概念 一&#xff0c;RocketMq安装和基本概念1&#xff0c;RocketMq基本安装(本地安装)2&#xff0c;Rocketmq的核心概念2.1&…

Linux使用ifconifg命令,没有显示ens33

Linux使用ifconifg命令&#xff0c;没有显示ens33 1.问题2.步骤2.1 查看虚拟机的组件是否启动了2.2 修改网络配置文件 ONBOOT修改为yes2.3 重启网络2.4 修改网络服务配置 3.解决 1.问题 打开虚拟机准备使用xshell连接时发现连接失败&#xff0c;在机器上查看ip发现ens33不现实…

Mysql主从搭建

Mysql主从搭建 1.Mysql下载1.1 查看操作系统2.2 下载mysql安装包 2.Mysql安装2.1 解压2.2 目录重命名2.3 创建data&#xff0c;存储文件2.4 创建用户组2.5 授权用户2.6 配置环境变量2.7 编辑my.cnf2.8 创建相关目录和文件2.9 初始化数据库2.10 复制mysql.server到/etc/init.d/下…
最新文章