网站详情页链接怎么做孝感市网站建设公司
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:24
当前位置: 首页 > news >正文
网站详情页链接怎么做,孝感市网站建设公司,网站运营方案书,广告设计专业术语目录 一、进程创建1.1 写时拷贝1.2 frok的常规用法1.3 fork调用失败的原因 二、进程终止2.1 进程退出码2.2 进程退出方式2.2.1 exit函数的使用2.2.2 _exit函数的使用2.2.3 exit函数与_exit函数的区别 2.3 进程信号 三、进程等待3.1 进程等待的必要性3.2 进程等待的方式3.2.1 wa… 目录 一、进程创建1.1 写时拷贝1.2 frok的常规用法1.3 fork调用失败的原因 二、进程终止2.1 进程退出码2.2 进程退出方式2.2.1 exit函数的使用2.2.2 _exit函数的使用2.2.3 exit函数与_exit函数的区别 2.3 进程信号 三、进程等待3.1 进程等待的必要性3.2 进程等待的方式3.2.1 wait函数3.2.2 waitpid函数 3.3 获取子进程的状态信息(status)3.4 阻塞等待3.5 非阻塞等待3.6 wait与waitpid的区别 一、进程创建 关于进程创建这个话题其实在之前我们就已经讲的差不多了利用fork函数从已存在进程中创建一个新进程新进程为子进程而原进程为父进程。返回值自进程中返回0父进程返回子进程id出错返回-1。 进程调用fork当控制转移到内核中的fork代码后内核做 分配新的内存块和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加子进程到系统进程列表当中fork返回开始调度器调度 fork之前父进程独立执行fork之后父子两个执行流分别执行: 1.1 写时拷贝 通常父子代码共享父子再不写入时数据也是共享的当任意一方试图写入便以写时拷贝的方式各自一份副本。具体见下图 1.2 frok的常规用法 一个父进程希望复制自己使父子进程同时执行不同的代码段。例如父进程等待客户端请求生成子进程来处理请求。一个进程要执行一个不同的程序。例如子进程从fork返回后调用exec函数 1.3 fork调用失败的原因 系统中有太多的进程实际用户的进程数超过了限制 关于进程的创建使用fork函数我在之前的文章中已经全部讲到这里就不花太多时间进行讲解了。 二、进程终止 下面我们就来探究一下进程终止正常执行完成与进程异常的情况我们的重点肯定是要探究结果不正确的原因(因为结果正确了就代表我们一定程度上就完成了某项任务)而结果不正确又可以通过一些方式来进行判断所以接下来我们将来谈谈退出码。 2.1 进程退出码 进程退出码exit code是一个整数用于表示一个进程在执行完成后的状态。当一个进程完成执行并退出时它会返回一个退出码该退出码通常是一个非零整数或者是0。一个非零的退出码通常表示进程执行过程中出现了错误或异常情况而0则通常表示进程执行成功。进程退出码的范围通常是0到255之间的整数。 我们平时最常见的int main() {return 0;} 退出码为0我们一般默认这个进程执行成功而!0表示进程执行过程中出现了错误或异常情况我们可以知道!0是有很多种情况的具体的退出码含义因操作系统和应用程序而异。通常每个应用程序会定义自己的退出码并在文档中提供退出码的含义说明例如1表示找不到该文件 2表示进程创建失败… 每个退出码都对应着解释说明此时进程的执行结果这也是为了方便后续进程出现某种错误时我们能够快速查找原因 下面我们通过一个例子来讲讲这个退出码 echo $? # 查看最近一次指令的退出码既然我们的退出码有很多中下面我们就来见一见这些退出码对应的文档解释我们将使用strerror这个库函数来进行展示它能够将退出码转化成对应的退出码信息 我们的退出码在不同的操作系统中可能数量、解释说明不一致大家下来可以在不同的操作系统中去查看一下退出码另外退出码对应的信息也有可能不会严格按照上面的标准打印信息这跟具体的指令实现有关我们自己也可以去定义这些退出码对应的信息。 2.2 进程退出方式 进程退出的方式我们在之前已经知道main函数return就是一个典型的进程退出方式那么我想问其他函数return呢它是否也代表进程退出 相信这个答案应该是非常明了的其他函数return仅仅代表该函数返回到调用该函数处而main函数return则是真正的进程退出这其实也说明进程执行本质其实是main执行流执行。 下面我们另外来介绍两种进程退出方式 exit函数退出exit(int status)status就代表进程的退出码它其实就等价于main函数return xxx但是它可以在代码的任意位置处调用都表示进程退出。_exit函数退出 2.2.1 exit函数的使用 接着我们在其他位置试试去调用exit函数看看会出现什么现象 结论exit函数在代码的任意位置被调用都表示该进程退出 2.2.2 _exit函数的使用 _exit函数跟exit函数的使用方式一样 2.2.3 exit函数与_exit函数的区别 我们在上述的例子中可以看到_exit函数与exit函数的使用方式一致这是否说明它们两者是一样的呢 其实exit函数内部封装了_exit函数 但在调用exit之前还做了其他工作 执行用户通过 atexit或on_exit定义的清理函数。关闭所有打开的流所有的缓存数据均被写入调用_exit 平时我们也建议一般用exit来终止进程。 2.3 进程信号 当进程异常时OS会向进程发送终止信号我们可以通过kill -l查看所有的终止信号 但是我们发现其中没有0信号当我们未接收到操作系统发出的信号时此时就为0信号代表进程正常执行而这些!0信号就是进程异常时操作系统发出的这些信号都是宏定义的我们可以在signum.h中查看 关于进程信号这里我们不做过多的讲解我们只是见见它们到了进程信号我再给大家具体讲解每种信号表示的含义。 三、进程等待 3.1 进程等待的必要性 之前讲过子进程退出父进程如果不管不顾就可能造成‘僵尸进程’的问题进而造成内存泄漏。另外进程一旦变成僵尸状态那就刀枪不入“杀人不眨眼”的kill -9 也无能为力因为谁也没有办法杀死一个已经死去的进程。最后父进程派给子进程的任务完成的如何我们需要知道。如子进程运行完成结果对还是不对或者是否正常退出。 Q为什么要存在进程等待 回收子进程资源避免内存泄露获取子进程执行结果 Q什么是进程等待 通过系统调用获取子进程退出码或者信号的方式顺便释放内存问题。 3.2 进程等待的方式 3.2.1 wait函数 wait函数的参数是输出型参数用来获取子进程退出的状态。如果不关心子进程退出的状态我们可以设置为 NULL。wait 函数的返回值成功返回被等待进程的 ID失败返回 -1。 while :; do ps axj | head -1 ps ajx | grep mytest | grep -v grep; sleep 1; echo ————; done
脚本代码每隔1s监测一下mytest进程的状态通过观察上述现象我们发现wait函数确实解决了僵尸进程占用资源的问题这里我们抛出一个问题父进程在等待的时候如果子进程没退出那么父进程在干什么 从上述图中我们观察到父进程使用wait函数我们的父进程确实是一直是处于阻塞状态在等待子进程结束子进程结束之后它才会执行相应的代码。那么有人会问了上述代码中在子进程结束之后使用了sleep休眠所以我们的父进程就一直在等待在子进程结束之后它才会结束啊这说的确实不无道理但是你去掉sleep之后去检测一下还是会出现相同的情况即父进程一直处于阻塞状态等待子进程结束 对于这个问题的回答其实是不准确的因为后面我们要讲的waitpid函数其实是可以通过参数来设置父进程在等待子进程时的状态的这一点我们在后续会讲到但是对于父进程调用wait函数来讲父进程一直处于阻塞状态等待子进程结束这个观点是完全没问题的
下面通过这个例子相信大家会对wait函数有一个更深的理解 Q父进程使用wait函数等待子进程结束将子进程的信息返回给父进程后才能执行父进程的代码吗 是的父进程使用wait()函数会等待其子进程退出后才会继续执行父进程的代码。wait()函数的作用是使父进程阻塞直到一个子进程退出为止。当有一个子进程退出时wait()函数会返回该子进程的进程状态信息。在父进程中调用wait()函数可以避免僵尸进程的产生同时也可以确保父进程在子进程执行完毕后再继续执行自己的代码。 另外我们还需知道在父进程中调用wait()函数时如果有多个子进程同时退出wait()函数会返回其中一个子进程的进程状态信息而不保证返回哪一个子进程的进程状态信息。如果需要获取所有子进程的退出状态可以使用waitpid()函数或者wait()函数的循环调用来实现。 关于wait函数的使用我们暂且就讲到这里因为后续的waitpid才是我们的重点它比起wait函数更加的灵活、功能也更加丰富我们最后也还会讲到它们之间的区别。 3.2.2 waitpid函数 waitpid函数相较于wait更为复杂但是也更加灵活、功能丰富。 我们先来看看waitpid函数的三个参数pid参数指定要等待的子进程ID、status参数用于存储子进程退出状态的信息、options参数用于指定等待的行为。 下面对这三个参数进行详细解析 pid参数可以指定要等待的子进程ID。 取值有以下几种 pid 0等待进程ID为pid的子进程结束。 pid 0等待与当前进程在同一进程组中的任何子进程结束。 pid -1等待任何子进程结束相当于wait()函数。 pid -1等待进程组ID为-pid的任何子进程结束。status参数是一个指向整型变量的指针用于存储子进程的退出状态信息其中包括退出状态和终止信号等信息。如果不关心退出状态可以将该参数设置为NULL。options参数是一个整型值用于指定等待的行为。 可以使用以下选项 WNOHANG如果没有已经结束的子进程则立即返回0而不是等待。 WUNTRACED如果子进程暂停了也会返回状态信息。 WCONTINUED如果子进程被继续了则返回状态信息。 如果不需要使用任何选项则可以将该参数设置为0。 waitpid()函数的返回值 waitpid()函数的返回值为已结束的子进程ID如果没有已结束的子进程且没有使用WNOHANG选项则当前进程会被挂起直到有一个子进程结束为止。 需要注意的是waitpid()函数可以多次调用以等待多个子进程的结束。每次调用可以等待一个指定的子进程或者等待任意一个子进程。 3.3 获取子进程的状态信息(status) 我们先简单的使用一下waitpid函数来获取子进程的status状态信息 我们的status其实主要存储着退出状态和进程信号等信息所以我们此时看到的结果肯定不可能只是一个退出码的结果。对于status这个整数我们不能将它看做一个完整的整数而应该看做位图位图是一种用一个或多个bit位来表示某种状态的一种数据结构换句话说其实status它其实是按照区域来划分的一个数据。 status的高16位全为0因为我们的退出状态一般为0~255用一个字节即可表示而进程信号只有64种使用一个字节完全就能表示了所以我们的低16位就用来表示退出状态和进程信号当然其实还有一个bit位是core dump标志实际上进程信号是用低7位来进行表示的。 我们来看看status使用运算符提取出退出状态和进程信号的方式 但实际上我们通常是使用两个宏函数来获取子进程的status状态信息 WEXITSTATUS()宏可以从waitpid()返回的状态信息中提取子进程的退出状态 WIFEXITED()宏可以检查子进程是否正常退出。 在获取到子进程的退出状态和进程信号后我们就能对子进程的执行结果进行判断了下面是关于退出状态与进程信号之间的关系。 结论本质上进程信号决定了退出状态是否有意义 下面我们来看看进程异常的情况 通过上图查看我们的status就能快速判断出进程的问题所在了。 我们知道父进程可以使用waitpid等待子进程结束去获取子进程的状态信息那么这个过程是怎么样的呢 3.4 阻塞等待 我们继续来谈前面抛出的问题父进程在等待的时候如果子进程没退出那么父进程在干什么 阻塞等待子进程没有退出前父进程一直在等待子进程退出不执行其他代码这种等待就是阻塞等待。 3.5 非阻塞等待 非阻塞等待就算子进程没退出父进程也不会一直等待子进程退出期间父进程会去执行它的代码过一段时间再来看子进程是否退出这种等待就是非阻塞等待。父进程每次检查子进程是否退出都是一次非阻塞等待多次非阻塞等待就是轮询的过程。 下面我们先来通过一个小故事感性理解一下阻塞等待和非阻塞等待 小库和阿耶莎是一对情侣这一天他们约好了在某个地方会合下午4点去xxx饭店吃饭小库到了集合地点之后给阿耶莎打电话问他到了没阿耶莎说再等等她她马上就好了于是小库没挂断就一直站在那儿静静等待着阿耶莎的到来。另外一种场景是小库到达集合地点给阿耶莎打电话问他到了没阿耶莎说还没呢你再等等于是小库就挂断电话想着阿耶莎还没到我可以先给她点一杯奶茶在她到达时看见我手中的奶茶想必我们关系更能加深一步在点完奶茶之后小库再次打电话给阿耶莎问她到了没此时阿耶莎说还没呢路上出了一点小问题你再等等吧于是小库又挂断了电话他想阿耶莎还没来我可以先买束花在这里等着她到时候阿耶莎看到之后应该会非常开心吧小库不愧是舔中之王啊 在买完花之后小库再次给阿耶莎打了一个电话阿耶莎说她到了于是小库拿着花返回集合地点。 上述故事中小库就对应父进程阿耶莎就对应子进程打电话就相当于系统调用waitpid阻塞等待就是第一种情形小库一直没挂电话等待阿耶莎到达目的地第二种情形小库在等待阿耶莎期间去做其他的事情就是非阻塞等待打电话给他然后挂断电话本质上就对阿耶莎做了一次状态检测小库打了很多次电话询问阿耶莎就是做了很多次检测这个过程叫做非阻塞轮询。 下面我们就来模拟一下非阻塞等待的情形 WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0父进程不予以等待可以执行它相应的任务。若正常结束则返回该子进程的ID。 3.6 wait与waitpid的区别 从本质上讲wait和waitpid的作用是完全相同的都是用于等待子进程结束的系统调用但是waitpid多了两个参数从而使我们的编程能更加的灵活。 等待的进程不同wait() 等待任意一个子进程结束而 waitpid() 可以指定等待某个特定的子进程结束。非阻塞等待在 wait() 中父进程会一直等待直到任意一个子进程结束如果没有子进程结束则父进程会一直阻塞。而 waitpid() 可以通过 WNOHANG 选项实现非阻塞等待即如果指定的子进程还没有结束则立即返回而不会阻塞等待。灵活性由于 waitpid() 可以指定等待某个特定的子进程结束并且可以进行非阻塞等待因此它比 wait() 更灵活更适合需要精细控制的情况。 总的来说wait() 和 waitpid() 的主要区别在于等待的进程、参数和阻塞等待的方式。根据具体的情况选择使用哪个函数会更加合适。 本篇文章的内容就到这里了如果有任何疑问或者错处欢迎大家评论区相互交流orz~
- 上一篇: 网站限定域名建设公司网站需要注意哪些
- 下一篇: 网站响应式和非响应式教人做美食视频网站
相关文章
-
网站限定域名建设公司网站需要注意哪些
网站限定域名建设公司网站需要注意哪些
- 技术栈
- 2026年03月21日
-
网站显示危险网站漳州公司注册
网站显示危险网站漳州公司注册
- 技术栈
- 2026年03月21日
-
网站显示速度的代码wordpress占用带宽
网站显示速度的代码wordpress占用带宽
- 技术栈
- 2026年03月21日
-
网站响应式和非响应式教人做美食视频网站
网站响应式和非响应式教人做美食视频网站
- 技术栈
- 2026年03月21日
-
网站响应式和非响应式邢台做wap网站找谁
网站响应式和非响应式邢台做wap网站找谁
- 技术栈
- 2026年03月21日
-
网站响应是什么青柠影院免费观看电视剧高清8
网站响应是什么青柠影院免费观看电视剧高清8
- 技术栈
- 2026年03月21日



