wait函数的作用

前言

在编写C程序的时候, 通过fork函数来创建新的进程, wait函数来等待子进程结束.

那么就有一个问题了, 什么情况下父进程需要等待子进程结束后继续执行呢? 如果需要等待子进程结束, 那直接将操作放到父进程执行不就醒了么? 反正等着也是等着.

当然, 还有有一种情况, 任务A 和任务 B 是后续操作的前提条件, 并且两个任务可以并行进行, 此时确实可以父进程执行一个, 子进程执行一个, 然后父进程等待子进程完成后继续操作. 但是, 我还是觉得这个解释并不是那么完美. 这完全可以通过进程通信实现啊.

因此, 我觉得wait函数的出现一定是有着其他用途的.

这个问题在我重翻操作系统之后有了答案.

为什么

众所周知, 进程在操作系统中运行的过程中是存在PCB(进程管理块)模块的. 它是进程的唯一标识符, 一般保存着PID运行状态资源信息等等.

进程在调用exit函数退出时, 会对占有的资源进行回收. 注意, 在exit函数回收资源的这段时间, 该进程仍然在运行中. 因此, 有一个资源是进程无法自己进行回收的, 就是PCB. 进程要运行就需要PCB, 而PCB回收的前提就是进程已经不在运行了. 也就是说, 进程自己是无法回收自己的.

那么PCB就无法回收了么? 当然不是, 该wait函数出场了. 既然进程自己无法回收自己, 那么就由父进程负责回收咯. 因此, 这么一个等待子进程结束的函数也就有了用武之地.

顺带一提, 在子进程exit执行结束, PCB资源回收之前的这段时间, 子进程的状态被称为僵尸态, 很形象了.

mac中的进程:

image-20220103213159252

debian中的进程:

image-20220103213318840

可以看到, PID为0的进程是所有进程的父进程. 在mac中, 所有进程都由/sbin/launchd进行创建, debian中则为kthreadd. 他们的作用就是对进程进行管理和调度. 父进程通过fork创建子进程, 之后子进程再通过exec更换为要执行的进程.

而这个PID为0的进程, 也是系统在运行过程中唯一一个不是通过fork创建的进程.

但是, 还有一个问题, 那就是如果父进程没有等子进程结束呢? 子进程结束的时候, 发现其父进程早就结束了, 那它的PCB 无法回收了么? 当然不会, 这个PID为0的祖宗进程, 或者称为root进程会定期扫描所有的僵尸进程, 并且代替其父进程对其进行回收.

了解了之后恍然大悟, そうですね!!!

原文地址: https://hujingnb.com/archives/733

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

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

相关文章

OAuth1.0介绍

背景 为什么需要OAuth授权呢? 最典型的应用场景就是第三方登录了, 我们开发了一个网站希望用户可以QQ登录, 但是怎么能拿到用户的 QQ 信息呢? 用户将 账号密码告诉我们当然可以, 但是这样有如下隐患: 我们拿到了用户的密码, 这样很不安全. 而且任意一个应用被黑, 所有相关…

PHP 数组的内部实现

前言 这几天在翻github的时候, 碰巧看到了php的源码, 就 down 下来随便翻了翻. 地址: https://github.com/php/php-src 那么PHP中什么玩意最引人注目嘞? 一定是数组了, PHP中的数组太强大了, 于是就想着不如进去看看数组的实现部分. 这篇文章打算全程针对代码进行解读了. 以…

go1.18新特性

前言 最近突然发现golang更新版本1.18了, 于是迫不及待的来看看这个版本加了些什么新特性. 没准就有之前困扰很久的问题, 在新版本被官方解决了呢. 先简单概述一下都有些什么变化, 后面再细说: 增加泛型的支持系统库方法增加修复 bug 另外, 像"系统内核更新"这种…

base64编码原理

引出 众所周知, ASICC编码共127个, 使用了7个bit进行编码. 而文件在存储的时候是以 字节为单位, 也就是8bit. 这就难免导致有一部分编码是没有定义在ASICC编码中的. 而在网络中传输二进制数据的时候(字符串本质上也是二进制数据嘛), 如果直接传输比特流, 倒也不是不可以, 只是…

页面加载速度-合并资源文件

前言 一直觉得自己的博客站点页面加载很慢, 就想着去优化一下. 呐, 下图是一次文章页面的加载, 需要2.5s. 其中 js 文件就有18个. 众所周知, 浏览器对资源文件的并行下载数量是有限制的(不同浏览器限制不同). 也就是说, 这18个 js 文件是无法同时下载的, 再说了, 页面中还有其…

hbase/thrift/go连接失败

问题 在通过Go连接hbase的过程中, 发现 get操作可以查到数据, 但是scanner命令访问数据失败, 也没有报错, 就是单纯的查不到数据. 而且Python PHP都一切正常. 这里简单复述一下我出现问题的情况, 安装过程和网上大部分内容一致, 这里简单列一下, 只是为了查询问题时参考安装过…

常用搜索引擎及语法

在平常需要进行搜索的时候是不是只知道Google Baidu ?? 他们其实是全文搜索引擎, 还有一些特定领域的搜索引擎. 而且, 搜索时可以添加特定语法, 让你的搜索事半功倍. 本文整理各种场景下使用的搜索引擎, 以及各个搜索引擎支持的语法, 不定期进行更新. 如果你知道其他搜索引…

自旋锁与互斥锁

前言 在编程中经常需要使用到互斥. 互斥就是, 这个事情只能有一个人干, 我正在做着的时候, 别人要想做这件事就得等我做完了. 互斥的实现是通过锁的机制, 也就是我把这块锁上了, 别人就进不来了, 等我做完再把锁释放掉. 但是, 前辈们已经证明了, 要想单纯的在软件层面上实现…

printf缓冲区踩坑

问题 碰到了这样一段代码(经过简化的): #include "stdio.h" #include "unistd.h" #include "sys/wait.h"int main(){fork();printf("1\n");fork();printf("1\n");wait(NULL);return 0; }这里我们简单算一下, 结果会打印几…

进程切换时是如何保存上下文的

前言 当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复. 当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中…

GO/testing包

前言 之前在写GO单元测试的时候, 使用了这个结构testing.T. 进来无事翻了翻, 发现testing包中还有一些其他的结构体, 想来是不同用处. 没想到GO的testing包竟然默默做了这么多支持, 之前竟然不知道. 在testing包中包含一下结构体: testing.T: 这就是我们平常使用的单元测试t…

CPU的分支预测

前言 最近在进行性能调优的时候, 碰到了这样的一段代码(为了展示问题而简化的代码): <?php // 第一次运行 $start microtime(true); for ($i 0; $i < 100; $i) {for ($j 0; $j <1000; $j) {for ($k 0;$k < 10000; $k) {}} } $end microtime(true); echo fi…

Golang Context 简介

前言 在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background(). 但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中…

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

RESTful API规范

前言 我现在工作的公司是在毕业前实习的公司, 实习结束后直接转正, 因此也是我任职过的唯一一家公司. 在日常工作进行 HTTP 接口的开发时, 发现了一个疑惑, 只用到了POST和GET请求, 但我们知道 HTTP还有PUT/DELETE等等, 为什么不用呢? 并且, 接口的响应码也只有200, 接口是…

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

Docker kill 1无效

前言 我们在平常强制停用一个进程的时候, 会选择什么命令? 一般在测试使, 不考虑程序突然中断带来的影响, 直接使用kill -9 pid强制停止就行. 但是, 就在刚刚, 我启动了一个docker容器, 进入容器后执行命令kill -9 1没有任何效果??? 啊这, 为什么呀? 尝试 为了解释这个…

容器内存相关知识

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看. 内存控制 使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢? 其实是操作系统已经做好了…

三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!

三星有子初长成气宇轩昂 秀美俊逸减之一分则嫌柔增之一分则嫌赘2019年8月7日于纽约巴克莱发布Galaxy Note 10系列用简约 重构美三星Galaxy Note 10与Galaxy Note 10分别搭载了6.3英寸和6.8英寸的超感官全视曲面屏&#xff0c;均采用单摄挖孔屏&#xff0c;开孔位于屏幕正上方。…