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

Linux----进程控制

进程终止

函数的返回值是做什么用的。函数返回值可以是return,或者exit():

可以用echo打印最近一个进程的退出码,当然也可以手动其他的值。

其实是子进程返回给父进程的退出码,用于处理子进程。

一个函数,执行完毕,结果正确,返回0;

执行完毕,结果错误,返回其他值,让程序员知道哪里出错了,可以手动设置错误信息

函数出现异常,没有执行完,给父进程传信号。

C语言中有strerror可以查看错误信息:

这是C语言数字对应错误的信息。

ll指令其实也是程序,当找不存在文件时就会报错,与2对应。ll就是用C语言写的。

return、exit()、_exit()的区别

return与exit()都可以为函数返回值:

但其实,exit()会引起当前进程的终止,如果不在main函数中写,而是在其中的任意一个函数写就会终止,不再执行下面的程序:

接下来说一说exit()与_exit()的区别,最大的区别就是_exit()是系统调用,执行进程直接中止,不会刷新缓冲区的内容,而exit()作为库中的函数,会刷新缓冲区的内容后,再终止进程:

而_exit():

所以缓冲区肯定不能在虚拟内存中的内核区部分,否则操作系统在终止一个进程肯定不会浪费这么一块资源。

都可以为函数返回值,但是exit()会直接终止进程,_exit()是系统调用,不会刷新缓冲区中的数据。

出现异常时

当进程出现异常时,会将发信号给父进程。如下都是异常的信号,可以使用kill指令让指定进程出现对应的异常

比如:

浮点数异常

进程等待

进程等待是通过系统调用wait/waitpid,来进行对子进程状态检测与回收的的功能。

解决僵尸进程

之前在进程状态时说过,僵尸进程不能使用kill或者ctrl+c杀死,只能通过进程等待来杀掉他,进而解决内存泄露问题。先看看僵尸进程是如何产生的:

可以通过wait()回收子进程资源:

创建多个子进程,并且回收资源:

如果子进程一直不结束,那么wait会使父进程阻塞,如果子进程结束,那么可以回收子进程资源。

退出信息

通过进程等待,获得子进程的退出情况,给子进程布置的任务他完成的怎么样了。

waitpid

这里要用到waitpid:

说明:如果pid参数为-1,效果与wait一致,可以等待任何进程;

如果pid>0,那么会等待对应id的进程

status为一个输出型参数,怎么理解呢?前面说了进程退出的三种情况:1.正常退出,结果正确;2.正常退出,结果错误;3.出现异常。

那么父进程在接收子进程信息时,就希望知道子进程是否出现异常,出现什么异常?子进程正常退出的话,结果是否正确?如不正确,出现什么错误了?所以在这种情况下,需要将这些信息写在status中。

status格式

可以看一个例子:

子进程退出1,返回的是256,其实就是2的8次方,就是status的第9个位置为1,子进程的退出码给到了status对应的位置。退出码、异常信号对应的值是多少,就填到上面图中对应的位置。

再看一个例子:浮点数错误,返回异常信号

宏信息

还可以使用宏函数来获取退出信息:

WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出),其实就是status&0x7F,如果为0,就返回真。

WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)其实就是(status>>8)&0xFF

返回状态为0,也就是假,有异常。

waitpid返回值

waitpid正常时,返回等待进程的pid,不正常时,会返回-1,当且仅当它接收的进程不是参数中的id的进程。

waitpid中第三个参数为WNOHANG时,父进程执行到waitpid时,如果子进程还没有结束,直接退出返回0,不会再阻塞等待子进程;而当其为0时,会阻塞等待子进程。

给子进程睡5秒,让父进程快些执行:

父进程没有阻塞等待子进程,先退出了,而子进程称为孤儿进程,父亲变成了init,执行完成后后被处理。

非阻塞轮询访问

如果我们希望用非阻塞的方式等待子进程呢?可以用到非阻塞轮询访问:不等待结果、主动反复检查状态 的一种工作方式。可以用循环+WNOHANG来实现:

进程程序替换

可以使用以下库函数进行程序替换:接下来会给出用法以及原理

单进程程序替换

举一个例子,可以看到在该进程中,并没有打印code end,而是打印code begin后执行了ls程序。这就是程序替换

原理

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换(原进程的代码、堆、栈、数据段都被覆盖),从新程序的入口函数开始执行,不会从原 main() 继续执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变(如进程号、父进程号、文件描述符表(可选保留)

多进程程序替换

可以看到在子进程内进行程序替换,并不会影响父进程的运行。因为进程间的独立性,子进程发生覆盖时,进行写时拷贝。

exec函数介绍

其中,第一个参数为path的,都是要给出命令(程序)所在的具体路径的,而file直接给出程序名就可以,他自己会去PATH中找对应的程序名;第二个参数一般都是如何执行命令的参数,比如*arg,....,这个是可变参数,可以带很多命令的选项,如果是argv,那么要将命令都写在这个数组中,注意,最后一个参数必须是NULL;有第三个参数的函数,可以所替换的程序传入对应的环境变量。

execl和execlp

可以使用其替换成自己写的程序

与之前ls的path不同,这里给出ls指令的名字就可以成功执行

execv和execvp

注意,参数数组要以nullptr为结尾。两个的区别与上面类似,第一个传入参数。

execle

该函数可以为替换程序传递,在讲这个函数之前,我们首先要清楚,即使我们不使用这个函数为替换程序传递环境变量,它自己也会继承父进程的环境变量:

隐式传环境变量

可以看到,project成功打印了父进程的环境变量,在这里我们使用了putenv函数为替换进程添加了一个环境变量BROTHER,这个环境变量在父进程中是没有的。为什么替换的程序会有父进程的环境变量呢?因为之前说过,进程的命令行参数与环境变量是存在用户虚拟空间中的

而进程程序替换只替换栈堆数据段和代码段的内容,不会替换别的内容,所以该程序依然存储着父进程的环境变量!

显式传环境变量

如果非要为替换进程传递环境变量呢?可以使用execle函数和environ变量。environ是一个全局变量指针,在所有使用 C/C++ 的进程中都存在。它保存了当前进程的 环境变量表

还可以自己定义环境变量,覆盖父进程环境变量:

environ

environ 是一个全局变量,保存当前进程的环境变量表(即 char **environ,指向一个以 NULL 结尾的字符串数组,每个元素形如 "KEY=VALUE")。我们可以通过它访问或修改环境变量,比如查看 PATH 或设置自定义变量。

在 C 程序中使用 environ 时,通常要加上extern char **environ;这是因为 environ 不是在当前源文件里定义的变量,而是在系统的 C 运行库(如 glibc)中定义的。extern 告诉编译器:“这个变量在别的地方定义,我这里只是引用它”。否则编译器会以为你要重新定义一个 environ,导致链接错误或与系统变量冲突。

总结

l(list) 表示参数采用列表
v(vector) 参数用数组
p(path) 有p自动搜索环境变量PATH
e(env) 表示自己维护环境变量

只有execve是真正的系统调用,其它五个函数最终都调用 execve。

调用其他语言

可以使用exec调用其他语言进程,如脚本:

还有python:

之所以可以使用 exec 调用由其他语言编写的程序,是因为 exec 本质上是在操纵进程:它让当前进程的程序内容被新的可执行文件替换,而不是创建新进程。
只要目标程序能够被编译或解释为可执行文件,在操作系统中能以进程形式运行,就可以被 exec 加载执行。

http://www.dtcms.com/a/554079.html

相关文章:

  • 公司网站建设公司微网站建设价格
  • AI代码开发宝库系列:RAG--GraphRAG实战
  • 做一份网站动态图多少钱免费ip地址
  • 基于空间螺旋运动假设的水星近日点进动理论推导与验证
  • 手写Spring第20弹:JDK动态代理:深入剖析Java代理模式
  • 京网站建设公司行业app开发公司
  • 平面设计网站导航dw软件代码大全
  • PyTorch生成式人工智能——MUNIT详解与实现
  • 建设微网站网站公司介绍模板
  • 网站为什么做微云的采集备案网站首页地址
  • [linux] rm命令
  • HTML加密工具EXE软件介绍
  • 大模型微调怎么实现?当然不是人工对一些参数微小调整!
  • TRAE SOLO:基于React 18+与蓝耘MaaS的多语言智能翻译平台设计与实现
  • 做网站编辑需要会什么深圳网络推广平台
  • 深入解析 MybatisPlus 中实现一对多查询的方法:以食谱餐别与菜单详情为例
  • 网站为什么不被收录做c2c网站的弊端
  • SMB签名关闭的安全风险探讨
  • 邵阳网站网站建设wordpress文章添加seo标题代码
  • 网站怎样做才会被百度收录湖北网站
  • Linux中释放初始化内存到伙伴系统free_initmem函数的实现
  • 58同城类似的网站开发云服务器网站建站
  • 商城类网站模板网站建好更新
  • Redis:我是如何与客户端进行通信的
  • 定制您的专属建站方案教育培训加盟
  • 高质量发展的“显著成效”:解读“十五五”对质与量协同增长的新要求
  • 网站建设生产或运营潭州学院网站建设报名
  • 做网站销售 优帮云市场推广计划方案
  • 移动的智慧:复合机器人开启24小时不间断上下料新纪元
  • Android Compose Dialog设置为底部显示