进程的基本概念、查看、创建

1. 进程的概念

概念:加载到内存的程序/正在运行的程序称为内存
我们在玩电脑的时候是可以启动多个程序的,比如边听歌边写博客,根据上篇文章我们知道肯定要将多个.exe文件加载到内存中,作为操作系统肯定是要管理这多个加载到内存的程序。如何管理呢?六个大字,先描述再组织。

2. 进程的描述

进程的信息被放在一个叫进程控制块(process control block)PCB,可以理解成一个进程属性的集合。
linux描述一个进程的结构体叫task_struct(PCB的一种)。该结构体有非常多的字段,我们挑几个常见的字段。

struct task_struct
{标识符:唯一标识符,用于区别其他进程状态:任务状态、退出代码、退出信号优先级:相对于其他进程的优先级程序计算器:程序中即将被执行的指令的地址上下文数据:进程执行时处理器的寄存器中的数据I/O状态:包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等....
}

3. 进程的组织

将多个进程描述成多个PCB结构体,再将各个PCB链接起来,所以对进程的管理就转化成对PCB结构体的管理。
在这里插入图片描述

所以一个进程等于:可执行程序(.exe)+内核数据结构(PCB)

4. 查看一个进程

使用ps指令来查看一个指令,下面是一个程序的代码,用于测试

int main()
{while(1){printf("I am a process!!!\n");sleep(1);}return 0;
}
ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep

在这里插入图片描述

PID就是上面说的标识符,可以使用系统函数getpid()获得,PPID则是父进程的标识符,可以使用getppid()。

int main()
{while(1){printf("I am a process!!! pid:%d ppid:%d\n",getpid(),getppid()");sleep(1);}return 0;
}

在这里插入图片描述

除了用ps指令查看一个进程,linux还将进程的信息存放在了一个叫proc的文件夹中。

在这里插入图片描述
我们来单独查看一个进程(PID为4630)是什么样的

在这里插入图片描述

5. 创建一个进程

运行一个程序就相当于创建一个进程,那么能用代码的形式创建一个进程吗?fork()函数就可以解决这个问题。
我们先来看一段代码:

  1 #include <stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 5 int main()6 {7     printf("before fork:pid: %d ppid: %d\n",getpid(),getppid());8     fork();9     printf("after  fork:pid: %d ppid: %d\n",getpid(),getppid());                                                                                                   10     return 0;11 }

在这里插入图片描述
可以看到fork之后有两个进程了,且它们是父子关系,fork()之后的代码共享。我们在来看看这个函数的原型。
在这里插入图片描述

再来看一段代码

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

在这里插入图片描述
从结果可以看出,如果是父进程fork的返回值是子进程的pid,而子进程的fork返回值是0,我们可以通过这个特性很好的分流执行代码。

  1 #include <stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 5 int main()6 {7     printf("before fork:pid: %d ppid: %d\n",getpid(),getppid());8     pid_t id = fork();9     if(id < 0)10         return -1;11     if(id == 0)12     {13         while(1)14         {15          printf("after  fork, 我是子进程:pid: %d ppid: %d returnid: %d\n",getpid(),getppid(),id);16              sleep(2);17         }18     }19     else20     {21         while(1)22         {23          printf("after  fork,我是父进程:pid: %d ppid: %d returnid: %d\n",getpid(),getppid(),id);24          sleep(2);                                                                                                                                                  25         }26     }27 28     sleep(2);29     return 0;30 }

在这里插入图片描述

看完简单的使用之后,我们再来思考三个问题?

fork为什么给父进程返回子进程的pid,而给子进程返回0?因为父进程有很多子进程,难以找到某个子进程,所以返回子进程的pid,但是子进程只有一个父进程,使用getppid就能得到父进程的pid了。

为什么一个函数会返回两个值?因为在fork这个函数内部,return语句之前的代码执行完之后,已经创建了子进程,所以会共享代码,return语句就执行了两遍。

为什么一个变量会有两个值?这个问题与进程地址空间有关,后面才会理解。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode_19_中等_删除链表的倒数第N个结点

文章目录 1. 题目2. 思路及代码实现&#xff08;Python&#xff09;2.1 计算链表长度2.2 栈 1. 题目 给你一个链表&#xff0c;删除链表的倒数第 n n n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a; h e a d [ 1 , 2 , 3 , 4 , 5 ] , n…

何时用‘x-->?‘将其代入lim中?极限的化简

【何时用‘x-->?将其代入lim中】 【极限的化简】 与极限解法区别&#xff1f; 方法有哪些&#xff1f; 什么条件下可以用&#xff1f; 怎么用&#xff1f;

第三篇:SQL数据模型、通用语法和语法分类

一&#xff0c;SQL数据模型 &#xff08;一&#xff09;关系型数据库&#xff08;RDBMS&#xff09; 1.概念 &#xff08;百度百科&#xff09;指采用了关系模型来组织数据的数据库&#xff0c;其以行和列的形式存储数据&#xff0c;以便于用户理解&#xff0c;关系型数据库这…

华为自动驾驶干不过特斯拉?

文 | AUTO芯球 作者 | 李诞 什么&#xff1f; 华为的智能驾驶方案干不过蔚小理&#xff1f; 特斯拉的智能驾驶[FSD]要甩中国车企几条街&#xff1f; 这华为问界阿维塔刚刚推送“全国都能开”的城区“无图 NCA” 就有黑子来喷了 这是跪久了站不起来了吧 作为玩车14年&…

openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志

文章目录 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志215.1 性能日志概述215.2 性能日志收集的配置参数 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志 215.1 性能日志概述 性能日志主要关注外部资源的访问性能问题。 性能日…

游泳耳机哪个牌子好?四大公认水下音质好的游泳推荐

游泳&#xff0c;一项促进全身健康的锻炼&#xff0c;不仅有益于肺活量的增加&#xff0c;还能提高大脑功能和兴奋度&#xff0c;从而增强体质和提高抗病能力。而在这美妙的运动中&#xff0c;选择合适的耳机&#xff0c;让音乐在水中荡漾&#xff0c;将游泳变得更为愉悦。 在…

【AIGC核心技术剖析】DreamCraft3D一种层次化的3D内容生成方法

DreamCraft3D是一种用于生成高保真、连贯3D对象的层次化3D内容生成方法。它利用2D参考图像引导几何塑造和纹理增强阶段&#xff0c;通过视角相关扩散模型执行得分蒸馏采样&#xff0c;解决了现有方法中存在的一致性问题。使用Bootstrapped Score Distillation来提高纹理&#x…

SpringMVC精简知识点

SpringMVC 数据格式化基本数据类型和字符串自动转换特殊数据类型和字符串自动转换 验证及国际化应用实例注意事项和使用细节注解的结合使用数据类型转换校验核心类-DatBinder取消某个属性的绑定中文乱码解决处理json和HttpMessageConverter<T>作业布置SpringMVC文件上传自…

C#,纽曼-康韦数(Newman Conway Number)的算法与源代码

John Henrry Newman 1 纽曼-康韦数 纽曼-康韦数&#xff08;Newman Conway Number&#xff09;序列是生成以下整数序列的序列。 1 1 2 2 3 4 4 4 5 6 7 7… 在数学上&#xff0c;纽曼-康韦数的序列P&#xff08;n&#xff09;由递推关系定义&#xff1a; (1) P&#xff08…

C/C++内存管理的底层调用逻辑

✨Blog&#xff1a;&#x1f970;不会敲代码的小张:)&#x1f970; &#x1f251;推荐专栏&#xff1a;C语言&#x1f92a;、Cpp&#x1f636;‍&#x1f32b;️、数据结构初阶&#x1f480; &#x1f4bd;座右铭&#xff1a;“記住&#xff0c;每一天都是一個新的開始&#x1…

【PWN · heap | House Of Spirit】2014_hack.lu_oreo

呜呜呜&#xff0c;时隔多个月&#xff0c;继续学pwn 目录 前言 零、House Of Spirit介绍 一、题目分析 二、调试过程 1.泄露libc 2.大量add设置fake chunk的size合法 3.message 构造fake chunk的next chunk合法&#xff0c;绕过检测 4.order释放&#xff0c;将fake ch…

如何在PS5上使用金手指修改游戏

环境&#xff1a;windows PS5 问题&#xff1a;PS5 没有GodHen&#xff0c;无法使用json金手指&#xff0c;PKG金手指比较少 解决办法&#xff1a;使用MultiTrainerv从网络注入PS5&#xff0c;修改进程内存 背景&#xff1a;为了护肝&#xff0c;拒绝刷刷刷 解决过程&#xff…