当前位置: 首页 > wzjs >正文

手机版刷赞网站建设盘古百度推广靠谱吗

手机版刷赞网站建设,盘古百度推广靠谱吗,阳光电子商务平台,怎样做3d动画短视频网站目录 前言 一 再识fork()函数 1.fork()函数的几个补充点 2.fork()函数创建子进程失败 二 进程终止 1. main()函数的返回值 2. 进程终止的常见做法 ​编辑 3._exit()和exit()函数的使用 4.进程终止后,内核做了什么? 三 进程等待 1.进程等待的…

目录

前言

一 再识fork()函数

1.fork()函数的几个补充点

2.fork()函数创建子进程失败

二 进程终止

1. main()函数的返回值

2. 进程终止的常见做法 

​编辑

3._exit()和exit()函数的使用

4.进程终止后,内核做了什么?

三 进程等待

1.进程等待的必要性

2.进程等待的方法

3. 获取子进程的status

🐳3.1waitpid的调用

 🐊3.2 宏:WEXITSTATUS()和WIFEXITED():


前言

我么在Linux:进程概念-CSDN博客这一章节中认识使用fork()函数来创建子进程,在Linux : 进程地址空间-CSDN博客这一篇详细介绍了父子进程的代码和数据共享的问题(写时拷贝)但是我们之前的实验都是为了演示子进程创建成功的现象,并没有说明子进程创建失败是什么结果。在Linux :进程状态-CSDN博客中我们提到了许多进程状态,其中提到了僵尸进程,这是一种在子进程退出时没有被父进程读取所产生的一种状态。所以在这篇文章中,我们再深入认识一下进程的终止和进程的等待


一 再识fork()函数

1.fork()函数的几个补充点

  • 在用fork函数创建子进程成功之后,子进程和父进程共享的是一份代码和数据,但是代码一般都是只读的,不能被修改,数据可以被修改,所以会发生写时拷贝。
  • 子进程创建成功之后,为什么子进程从fork()函数之后的代码开始执行,而不是从头开始?在CPU中存在一个寄存器叫程序计数器(eip),这个寄存器的作用是保存当前正在执行的指令的下一条指令,当子进程创建成功之后,父进程的程序计数器的内容会拷贝给子进程,因此子进程就会知道上次执行到哪一个地方,便会接着向下执行。

2.fork()函数创建子进程失败

  fork()函数创建失败的原因是跟操作系统中的进程的数量和进程所占用的资源有关。当操作系统      中的进程数量太多,如果接着创建进程会使操作系统管理不过来,或者当前操作系统中所剩的内    存资源不够再创建出一个进程来,这些情况下都会创建进程失败。


二 进程终止

我们在Linux :进程状态-CSDN博客中提到了进程终止,即在进程被正确回收之后,这里我们再进行详细介绍一下细节,首先我们需要明白一个进程的正常退出有几种情况:

  • 代码正常跑完,运行结果正确
  • 代码正常跑完,运行结果错误
  • 代码没有跑完,进程异常退出

1. main()函数的返回值

从我们开始编写第一个C/C++程序开始,我们在主函数的最后都要写上一行代码 return 0;相信我们大家都曾对它产生过疑问,以当时的知识储备我们只能理解表面,我们只知道,return 0表示的程序正常跑完,运行结果正确;非零表示程序正常跑完,运行结果不正确。那么这个零和非零究竟是什么呢?

return返回的这个数字是进程的退出码,其中0表示的是正常退出,结果正确,其他的非零就分别代表着结果运行不正确的原因,且退出码是返回给当前进程的父进程进行接收的,父进程需要知道自己子进程退出或者终止的原因,从而回收子进程的资源。

❶退出码 

我们之前在学习进程PCB的时候,知道每一个进程的task_struct中存储了许多和进程相关的属性和信息,其中就包括了退出码,如下:

那么怎么获取到进程的退出码呢?答:echo $?命令 

如上图,我们使用echo $? 命令,可以看到退出码为16,可是下图再执行echo $? 命令时候,为什么退出码变成0呢?

🎲因为$?永远记录最近一个进程 执行完毕对应的退出码。

第一个$?--------------->(main->return 16)

第二个$?--------------->(对应进程&?的退出码0)

$?是一个进程

❷退出码意义 

下面我们利用strerror函数将错误代码转换为相应的错误消息字符串打印出来看看。

2. 进程终止的常见做法 

㊀ :在主函数(main)中使用return返回,main函数是程序的入口,在主函数中使用return表示程序的结束(非主函数中只表示函数的调用结束,并不是程序的结束)。

㊁:在程序的任何地方使用exit()函数,exit()函数表示终止程序,在程序的任意位置调用它都可以让程序终止。

3._exit()和exit()函数的使用

➊ 首先用man 2 exit命令查看_exit()

➋ 我们分别使用exit()函数和_exit()函数退出一个程序看看区别

exit:可以看到进程正常退出且正常打印。

_exit()

 所以区别显而易见了,一个在进程退出的时候打印了,一个没有打印。

我们知道,在使用printf语句进行打印的时候,打印的内容并不会立马刷新到外设,首先会暂存到缓冲区中,在上面的程序中,我们并没有使用‘\n’直接刷新缓冲区。当我们使用exit()函数时,缓冲区的东西能刷新到显示器上,但是使用_exit()函数时却不会。这表明,exit()函数在终止程序的时候会刷新缓冲区,_exit()函数在终止程序的时候不会刷新缓冲区。

exit/_exit/return区别 

  • exit()是C语言的接口,_exit()属于系统调用。
  • exit()属于正常的退出进程,它可以用于任意的函数中,通过调用它使得整个进程退出。且通过返回一个退出码将控制权交还给操作系统。
  • exit()最后也会调用_exit()函数来直接终止程序,但是在调用_exit()之前,它还会干点其他的事情,比如会执行用户定义的清理函数和刷新缓冲区关闭对应的流等。
  • _exit()是直接终止程序,不返回任何状态给操作系统。
  • return语句用于退出函数和方法,并将控制权返回到调用该函数或者方法的位置。
  • return语句只能用于函数或方法的内部,而不能使整个进程退出。当函数或方法中的所有代码都执行完毕或者遇到return语句,该函数或方法的执行将结束,控制权返回给调用者。

再谈return 

上面提到的return是一种更加常见的退出进程的方法,执行return n;语句等同于执行了exit(n),因为调用main()函数的运行的时候函数会将main()的返回值当作exit的参数。

4.进程终止后,内核做了什么?

我们知道,一个进程是由自己的内核数据结构和进程代码和数据组成的,当一个进程退出的时候,首先自己的进程状态会变成Z状态,也就是所谓的僵尸状态,此时需要等其父进程对其进程回收,由终止我们知道其需要给其父进程返回退出码,这个进程的状态马上变成X状态,其父进程的相关代码会回收(释放)其数据和相关代码,因为当该进程终止的时候,其数据和代码已经没有任何意义了


三 进程等待

1.进程等待的必要性

  • 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
  • 另外,进程一旦变成僵尸状态,kill -9 也无能为力,因为谁也没有办法 杀死一个已经死去的进程。 最后,父进程派给子进程的任务完成的如何,我们需要知道。如子进程运行完成,结果对还是不对, 或者是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

2.进程等待的方法

wait方法

wait()返回值: 成功则返回被等待进程pid,失败返回-1。 

从运行结果我们能看出,刚开始子进程和父进程都是休眠状态(S+),因为要打印,需要与显示器交互,所以处于休眠状态,

当子进程exit(0)退出的时候,父进程还在,此时子进程变成僵尸状态(Z+),等待父进程回收读取退出信息

wait() 之后,子进程被父进程成功读取

状态变成X,此时只有父进程状态

父进程sleep 5 秒之后,父进程会被bash回收,所以最后,父进程的状态也不存在了。

并且我们可以看到wait的返回值是子进程的pid.

waitpid()方法

 waitpid()包含三个参数,但是其返回值和wait()调用相同,若返回值 > 0 返回值即为等待的子进程的PID; 若返回值 = -1, 即为调用失败, errorno会被设置为错误提示码; 先来看它的三个参数:

  • pid_t pid:这里传入的是被等待进程的pid,即指定特定的pid让父进程等待。当传入-1时,waitpid()与wait()的作用相同,都是等待任意的子进程。

  • int *status:一个指针参数(输出型参数),此参数的作用是向外部传递信息,当 waitpid()此函数等待到一个退出的子进程的时候,子进程的退出信息会被存储到 status指针指向的内容中。这两个调用都是系统调用。
    int options:更像是一个配置参数,通过传递不同的参数,可以让waitpid()有着不同的工作模式。当传入0时,表示阻塞等待,即waitpid()的工作模式就像是阻塞一样, 如果其等待的子进程还未退出, 那么父进程就会一直阻塞等着子进程退出, 在子进程退出之前, 父进程一直处于阻塞状态, 不会做其他事情, 就只是等着子进程退出。

3. 获取子进程的status

上面我们讲到wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。如果传递NULL,表示不关心子进程的退出状态信息。status不能简单的当作整形来看待,可以当作位图来看待,如下图(只研究status低16比特位)

也就是说,waitpid()使用的第二个参数是一个int类型变量的地址 ,当waitpid()等待到一个子进程后,传入的地址所指向的变量的低16位中,低八位表示子进程的退出信号,高八位表示子进程退出码。 并且,当子进程是正常退出时,表示退出信号的八位为0;当子进程被某种信号所杀时,表示退出码的八位为0. 

关于退出信号和退出信号的计算,退出码((status>>8)&0xFF),退出信号(status&0x7F),(status>>8)&0xFF表示的是取status中的第二个八位数,即从第9到第16位的数字,这部分的数字代表退出进程的退出码。退出信号的计算是status&0x7F,但是最高位是一个单独的core_dump标志,暂时忽略。

✍注: 当进程退出码为0时, 往往意味着进程正常退出.而此时子进程接收到信号而退出, 肯定是不属于正常退出的范围的.而子进程的退出码依旧是0?是否与退出信号冲突了?当然没有, 当退出信号不为0时, 退出码就没有意义了, 可以忽略不看

🐳3.1waitpid的调用

程序跑完,结果不正确(退出信号为0,退出码非零)

退出信号为0,说明代码跑完,退出码为10,说明结果不对(这里代码exit(10)抽象认为某种原因结果不对)。 

 程序跑完,结果正确(退出信号为0,退出码为零)

代码没跑完,程序出异常了,这个时候不需要关注退出码结果了

运行结果

 🐊3.2 宏:WEXITSTATUS()和WIFEXITED()

父进程中的status变量接收到数据之后, 其实不需要通过手动位运算来计算出子进程的退出码和退出信号.其实而可以通过两个宏:

WIFEXITED(status): 若子进程正常退出(即程序跑完了,退出信号为0),则为真。

WEXITSTATUS(status): 提取子进程退出码,判断运行结果对不对。

exit code:10说明程序跑完了,正常退出,退出码为10

http://www.dtcms.com/wzjs/29715.html

相关文章:

  • 如何套用别人网站模板软文范例800字
  • 要怎么做网站成都seo招聘
  • 长沙网站建设服务公司最新国际新闻
  • 卖酒的网站做线下怎么做百度网盘app官网下载
  • 简述上课网站建设所用的技术架构北京cms建站模板
  • 门户网站设计方案社群营销
  • 模板网站建设包括哪些爱站工具包下载
  • 云南做网站的公司郑州搜索引擎优化
  • 泰州做企业网站疫情放开死亡人数最新消息
  • 怎么制作钓鱼网站百度搜索优化平台
  • 做商品网站的教学视频教程病毒式营销
  • 上门按摩怎么做网站泉州关键词优化软件
  • 网站企业建站什么推广方式能快速引流
  • 网站建设如何吸引投资什么是关键词广告
  • 昆山做网站的公司有哪些网站怎么才能被百度收录
  • 湖北电商的网络推广重庆百度整站优化
  • 网站必须公安备案吗seo推广方法有哪些
  • 教育网站设计欣赏网络推广图片
  • 杭工e家app是哪个网站做的中国体育新闻
  • 做徽章的网站网络营销首先要做什么
  • 做餐饮连锁在哪个网站看seo jsbapp9
  • 做网站背景全网自媒体平台大全
  • 怎样用手机搭建网站宁波优化推广找哪家
  • b2c网站建设软文广告500字
  • 山西省住房和城乡建设厅网站报名策划网络营销活动
  • 凡客诚品官方网址seo流量
  • 镇江网站建设制作女教师遭网课入侵直播录屏曝光i
  • axure中继器做网站网络推广有多少种方法
  • 个人能免费做网站外贸接单十大网站
  • 杭州做卖房子的工作哪个网站好怎样把个人介绍放到百度