【Linux系统】进程概念创建进程进程标示符

什么是进程?

操作系统中, 进程可以同时存在非常多的。根据我们之前谈的操作系统具有“管理”的特性, 那么就有,既然要管理,就要 --- 先描述,在组织!!!

 由冯诺依曼体系结构我们知道磁盘中的文件都是要加载到内存然后由内存与CPU交互完成一些任务的。

所以其实当我们运行一些程序时就会为我们创建一个进程。

这个进程是什么样的?

那么当我们运行我们写出来的c/c++代码时。

首先从磁盘中把我们的代码和数据加载到内存中

一个进程就要有一个PCB(process control block)

这个PCB要在内存中加载的操作系统中malloc出对应的空间,实质上就是一个结构体类型,

里面包含了各种进程有关的属性,并且有一个指针可以指向自己的代码和数据!!!

那么我们得出一个结论:进程 = PCB + 程序的代码和数据

 在后面我们就可以把内存中加载的操作系统内部进行各种PCB的管理工作,也就是说

我们对进程的管理就转变成了我们对链表(各种数据结构,不一定就是链表)的增删查改!!!

具体到Linux中的进程是什么样的?

 我们前面知道了:进程 = PCB + 自己的代码和数据

这里的PCB是一个统称,因为我们将来要接触各种各样的操作系统, 他们的PCB实现当然是不同的,名字可能也有差异。

那具体到Linux中是怎么样的呢?

struct task_struct

{

        //Linux控制块

}

这里的task_struct就是具体的称呼!!!

 下面就理解一个概念:如何理解进程动态运行?

 只要我们的进程task_struct将来在不同的队列中,进程就可以访问不同的资源!!!

 故有:调度运行进程,本质就是让进程块task_struct进行排队!!!

进程task_struct内部的属性有哪些?

标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息

 这些是task_struct内部的一些属性名称,我们后续都将一一学习。

如何启动一个进程?

 a. 

我们在Linux中的./xxx本质就是让系统启动进程并运行 === 我们写的代码形成可执行 ===

系统命令 === 可执行文件。

所以:在Linux中运行中的大部分执行操作,本质都是运行进程!!!

 我们在Linux中也可以查看进程

通过ls /proc命令

进程的标识符

每个进程都有自己的唯一标识符,叫做进程pid

一个进程,想知道自己的pid???

如何做呢?

那么问题来了,我们能直接访问操作系统来查询自己的pid吗?答案是不能的

我们已经讲过用户想要访问操作系统的内容就必须要通过操作系统提供的系统调用接口来获取内部信息!!!

 那么如何获取我们进程的pid呢?

就使用getpid这个接口即可获取到我们需要的进程pid信息!!!

 

  #include<stdio.h>
  #include<sys/types.h>
  #include<unistd.h>
  
  int main()
  {
      pid_t pid = getpid();
      printf("pid:%d\n", pid);
      sleep(1);                                                                                     
      return 0;                                                  
  }     

 

 我们来创建一个一直在跑的进程,方便我们查看进程

  1 #include<stdio.h>  
  2 #include<sys/types.h>  
  3 #include<unistd.h>  
  4   
  5 int main()  
  6 {  
  7     pid_t pid = getpid();
  8 
  9     while(1)                                                                                      
 10     {                           
 11         printf("pid:%d\n", pid);
 12         sleep(1);
 13     }
 14              
 15     return 0;
 16 }

 

 这是我们的进程在运行,我们看到pid就是属性栏的第二列就是我们该进程自己的pid。

显然ctrl + c就是在用户层面终止程序

kill + -9 + pid 可以用来直接杀掉进程

进程创建的代码方式(重操作,轻原理 --- 后续会再次详谈进程创建)

 

 getpid():获取当前进程的pid

getppid():获取当前进程的父进程pid

在Linux中所有的进程又有一个统一的父进程,就是bash --- 命令行解释器

比较方便查看进程的一个xshell脚本:while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep ; sleep 1; done
 

而我们接下来要学习一个新的接口,他能够为我们创建子进程

fork();

 

 fork之后父子代码共享!!!

创建一个进程本质就是系统多了一个进程

多了个进程就是多个

1.内核task_struct

2.有自己的代码和数据

父进程的代码和数据是由磁盘加载而来的。

那么子进程的代码和数据呢???

默认情况下继承父进程的代码和数据?

 我们为什么要创建子进程,我们是要子进程执行和父进程不一样的代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret < 0){
perror("fork");
return 1;
}
else if(ret == 0){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}

 对于fork两个问题

1.同一个id,怎么可能即是0又是一个大于0的数

2.fork会有两个返回值,返回两次

对于第一个问题现在我们还不能很好的解释后续再谈

第二个问题

我们知道

进程 = 内核数据结构task_struct + 代码和数据

进程一定要独立,进程具有独立性

所以父子各自独立,原则上数据要分开

且代码是只读的

子进程会继承父进程的代码,又代码是只读的,所以fork函数内部必定是要先去创建子进程的

然后进行返回id,但我们知道子进程是完全继承父进程的代码的,故会返回两次值。

我们在后续可以一次性创建多个进程

进程的PCB中会记录自己对应的可执行程序的路径 -》 exe -> 路径

也会记录该进程当前的工作路径 -》 cwd -> 路径

 chdir("");这个函数可以改变我们的进程工作路径!!!

结论:每个进程在启动时都会记录自己在当下哪个路径启动,进程的当前路径!!!

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

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

相关文章

AIGC,ChatGPT,Prompt 万能提示词

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 Mysql 8.0 54集 Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 51集 Excel 2021实操 100集&#xff0c; Excel 2021函数大全 80集 Excel 2021…

进入消息传递的魔法之门:ActiveMQ原理与使用详解

嗨&#xff0c;亲爱的童鞋们&#xff01;欢迎来到这个充满魔法的世界&#xff0c;今天我们将一同揭开消息中间件ActiveMQ的神秘面纱。如果你是一个对编程稍有兴趣&#xff0c;但又对消息中间件一知半解的小白&#xff0c;不要害怕&#xff0c;我将用最简单、最友好的语言为你呈…

Linux——命名管道

Linux——命名管道 命名管道命名管道和匿名管道的区别 创建命名管道利用命名管道实现简单通信 我们之前学习了匿名管道&#xff0c;这种管道有一个缺点就是只有两个有血缘关系的进程才能够使用匿名管道&#xff0c;这个非常不方便。所以我们又在匿名管道的基础之上引入了命名管…

Flask python :logging日志功能使用

logging日志的使用 一、了解flask日志1.1、Loggers记录器1.2、Handlers 处理器1.3、Formatters 格式化器 二、使用日志2.1、官网上的一个简单的示例2.2、基本配置2.3、具体使用示例2.4、运行 三、写在最后 一、了解flask日志 日志是一种非常重要的工具&#xff0c;可以帮助开发…

系列学习前端之第 7 章:一文掌握 AJAX

1、AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML&#xff08;中文名&#xff1a;阿贾克斯&#xff09;&#xff0c;就是异步的 JS 和 XML。AJAX 不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方式。AJAX 可以在浏览器中向服务器发送异步请求…

flutter 弹窗之系列一

自定义不受Navigator影响的弹窗 class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;overrideState<MyHomePage> createState() > _MyHomePageState(); }class _MyHomePageState extends State<MyH…

rabbitmq-c 程序实现客户端服务端

安装mq https://blog.csdn.net/zl_momomo/article/details/82986368 需要安裝rabbitmq-server 开启rabbitmq服务 systemctl start rabbitmq-server systemctl enable rabbitmq-server. 客户端 amqp_sendstring.c include <stdint.h> #include <stdio.h> #incl…

访问二维数组本质

先从一维数组讲起 int main() {int arr[5] { 1,2,3,4,5 };for (int i 0; i < 5; i) {printf("%d",arr[i]); //对数组进行访问}return 0; } 其实 arr [ i ] * (arr i) 这两个是完全相等的&#xff0c;在c语言指针&#xff08;1&#xff09;8.数组名与 …

STM32F103 CubeMX 使用USB生成键盘设备

STM32F103 CubeMX 使用USB生成键盘设备 基础信息HID8个数组各自的功能 生成代码代码编写添加申明信息main 函数编写HID 修改1. 修改报文描述符2 修改 "usbd_hid.h" 中的申明文件 基础信息 软件版本&#xff1a; stm32cubmx&#xff1a;6.2 keil 5 硬件&#xff1a;…

Redis中的事件(三)

时间事件 事件的调度与执行 因为服务器中同时存在文件事件和时间事件两种事件类型&#xff0c;所以服务器必须对这两种事件进行调度&#xff0c;决定何时应该处理文件事件&#xff0c;何时有应该处理时间事件&#xff0c;以及花多少事件来处理它们等等。事件的调度和执行由ae…

uniApp中使用小程序XR-Frame创建3D场景(2)加载模型

上篇文章讲述了如何将XR-Frame作为子组件集成到uniApp中使用&#xff0c;只完成了简单的环境搭建&#xff0c;这篇文章讲解如何加载3D模型。 1 加入模型加载标签 在XR-Frame框架中&#xff0c;加载资源都是在wxml文件的标签中实现的。下面是wxml中完整的代码 index.wxml &l…

(二)Eureka服务搭建,服务注册,服务发现

1.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 存在几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

手机和键盘的数字键盘排序为什么是不同的?

不知道你有没有注意有一个问题。我们的手机输入法中的数字键盘&#xff0c;电脑上通用的数字键盘&#xff0c;计算器上的数字键盘等排序是不同的&#xff0c;从观察者角度看&#xff0c;0-9的数字排列有从上到下的排列&#xff0c;还有从下到上的排列。为什么会出现不同的排列方…

HWOD:句子逆序

一、题目 描述 将一个英文语句以单词为单位逆序排放。例如I am a boy逆序排放后为boy a am I。所有单词之间用一个空格隔开。语句中除了英文字母外&#xff0c;不再包含其他字符。 数据范围 输入的字符串长度满足 1<n<1000 输入 输入一个英文语句&#xff0c;每个…

【电力监控保护】AM5SE-IS防孤岛保护装置/35kV、10kV、380V分布式光伏并网供电/什么是孤岛效应/孤岛效应的危害

什么是孤岛效应&#xff01;&#xff01;&#xff01; 安科瑞薛瑶瑶18701709087 在电力系统中&#xff0c;孤岛效应指的是当电网突然断电时&#xff0c;并网光伏发电系统仍然保持对电网中部分线路的供电状态。这种情况下&#xff0c;这些线路与其他电网断开&#xff0c;形成了…

HarmonyOS页面布局方式

Column&Row组件的使用 1 概述 一个丰富的页面需要很多组件组成&#xff0c;那么&#xff0c;我们如何才能让这些组件有条不紊地在页面上布局呢&#xff1f;这就需要借助容器组件来实现。 容器组件是一种比较特殊的组件&#xff0c;它可以包含其他的组件&#xff0c;而且…

亚马逊美国站CPC认证婴儿门栏和围栏安全标准cpsc办理

美国ASTM F1004-19认证属于婴幼儿门栏和围栏安全标准 ASTM F1004-19婴幼儿门栏和围栏安全标准 2020年7月6日&#xff0c;美国消费品安全委员会发布了最终法规16 CFR 1239&#xff0c;为婴幼儿门栏和围栏建立了安全标准。该法规合并及修订了最新版本的ASTM F1004-19《婴幼儿扩展…

【分布式】——降级熔断限流

降级&熔断&限流 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点…

API网关-Apisix路由配置教程(数据编辑器方式)

文章目录 前言一、端口修改1. apisix 端口修改2. dashboard 端口修改3. 登录密码修改 二、常用插件介绍1. 常用转换插件1.1 proxy-rewrite插件1.1.1 属性字段1.1.2 配置示例 2. 常用认证插件2.1 key-auth插件2.1.1 消费者端字段2.1.2 路由端字段2.1.3 配置示例 2.2 basic-auth插…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…