【玩转Linux】如何快速理解进程概念
发布时间 - 2025-06-19 00:00:00 点击率:次冯诺依曼体系结构
我们常见的计算机,如笔记本电脑,以及不常见的计算机,如服务器,大部分都遵循冯诺依曼体系结构。
截至目前,我们所认识的计算机,都是由一个个的硬件组件组成的。
输入单元:包括键盘、鼠标、扫描仪、写板等。
中央处理器(CPU):包含运算器和控制器等。
输出单元:显示器、打印机等。
关于冯诺依曼体系结构,必须强调几点:
- 这里的存储器指的是内存。
- 不考虑缓存情况,这里的CPU只能对内存进行读写,不能直接访问外设(输入或输出设备)。
- 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
- 一句话,所有设备都只能直接与内存打交道。
操作系统(Operator System)概念
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统地理解,操作系统包括:
- 内核(进程管理、内存管理、文件管理、驱动管理)。
- 其他程序(例如函数库、shell程序等)。
设计OS的目的是与硬件交互,管理所有的软硬件资源,为用户程序(应用程序)提供一个良好的执行环境。操作系统在整个计算机软硬件架构中的定位是一款纯正的“搞管理”的软件。
如何理解“管理”?
管理的例子描述被管理对象,组织被管理对象。
进程基本概念
课本概念:程序的一个执行实例,正在执行的程序等。
内核观点:担当分配系统资源(CPU时间、内存)的实体。
描述进程-PCB
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block),Linux操作系统下的PCB是:task_struct。
task_struct-PCB的一种
在Linux中描述进程的结构体叫做task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_struct内容分类
- 标示符:描述本进程的唯一标示符,用来区别其他进程。
- 状态:任务状态、退出代码、退出信号等。
- 优先级:相对于其他进程的优先级。
- 程序计数器:程序中即将被执行的下一条指令的地址。
- 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
- 上下文数据:进程执行时处理器的寄存器中的数据。
- I/O状态信息:包括显示的I/O请求、分配给进程的I/O设备和被进程使用的文件列表。
- 记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制、记账号等。
- 其他信息。
组织进程可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
查看进程
进程的信息可以通过/proc系统文件夹查看。
通过系统调用获取进程标示符
进程ID(PI
D)和父进程ID(PPID)。
#include#include #include int main(){ printf("pid: %d\n", getpid()); printf("ppid: %d\n", getppid()); return 0; }
通过系统调用创建进程-fork
初识运行man fork,认识fork。fork有两个返回值,父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)。
#include#include #include int main(){ int ret = fork(); printf("hello proc : %d!, ret: %d\n", getpid(), ret); sleep(1); return 0; }
fork之后通常要用if进行分流。
#include#include #include int main(){ int ret = fork(); if(ret == 0){ //子进程 }else if(ret > 0){ //父进程 }else{ //错误处理 } return 0; }
进程状态
/** The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};- R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠interruptible sleep)。
- D磁盘休眠状态(Disk sleep),有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止(T)进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行。
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
进程状态查看
ps aux / ps axj 命令
Z(zombie)-僵尸进程
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
来一个创建维持30秒的僵死进程例子:
#include#include int main(){ pid_t id = fork(); if(id > 0){ //父进程 printf("parent[%d] is sleeping...\n", getpid()); sleep(30); }else{ printf("child[%d] is begin Z...\n", getpid()); sleep(5); exit(EXIT_SUCCESS); } return 0; }
僵尸进程危害
进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!内存泄漏---
进程状态总结
孤儿进程
父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?父进程先退出,子进程就称之为“孤儿进程”。孤儿进程被1号init进程领养,当然要有init进程回收喽。
#include#include #include int main(){ pid_t id = fork(); if(id > 0){ //父进程 printf("parent[%d] is exiting...\n", getpid()); exit(EXIT_SUCCESS); }else{ //子进程 printf("child[%d] is sleeping...\n", getpid()); sleep(30); exit(EXIT_SUCCESS); } return 0; }
学习编程就得循序渐进,扎实基础,勿在浮沙筑高台。
# linux
# 操作系统
# 处理器
# 电脑
# ai
# 区别
# linux操作系统
# igs
# 架构
# if
# 结构体
# 指针
# 数据结构
# operator
# 对象
# 事件
# 可以通过
# 要用
# 在等待
# 高台
# 外设
# 称之为
# 是一个
# 就会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
,网页ppt怎么弄成自己的ppt?
googleplay官方入口在哪里_Google Play官方商店快速入口指南
Linux系统运维自动化项目教程_Ansible批量管理实战
在线制作视频的网站有哪些,电脑如何制作视频短片?
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
Android okhttputils现在进度显示实例代码
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
如何在云虚拟主机上快速搭建个人网站?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
详解MySQL数据库的安装与密码配置
HTML 中动态设置元素 name 属性的正确语法详解
如何在建站宝盒中设置产品搜索功能?
如何在阿里云通过域名搭建网站?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Laravel如何创建自定义Facades?(详细步骤)
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
香港服务器建站指南:免备案优势与SEO优化技巧全解析
高防服务器租用指南:配置选择与快速部署攻略
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
打造顶配客厅影院,这份100寸电视推荐名单请查收
如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)
如何在阿里云完成域名注册与建站?
Laravel如何为API编写文档_Laravel API文档生成与维护方法
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
EditPlus中的正则表达式实战(5)
Laravel Fortify是什么,和Jetstream有什么关系
Laravel如何集成Inertia.js与Vue/React?(安装配置)
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
如何在IIS中新建站点并配置端口与物理路径?
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
如何在IIS中新建站点并解决端口绑定冲突?
Python并发异常传播_错误处理解析【教程】
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
高防服务器:AI智能防御DDoS攻击与数据安全保障
如何基于云服务器快速搭建个人网站?

