欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 【linux学习指南】进程创建与终止

【linux学习指南】进程创建与终止

2025/1/4 10:05:59 来源:https://blog.csdn.net/a_hong_sen/article/details/144856712  浏览:    关键词:【linux学习指南】进程创建与终止

加粗样式
请添加图片描述

文章目录

  • 📝进程创建
  • 🌠 fork函数初识
    • 🌉fork函数返回值
  • 🌠 写时拷⻉
    • 🌉fork常规⽤法
    • 🌉fork调⽤失败的原因
  • 🌠进程终⽌
    • 🌉进程退出场景
    • 🌉进程常⻅退出⽅法
    • 🌉退出码
    • 🌉_exit函数
    • 🌉exit函数
    • 🌉return退出
  • 🚩总结

📝进程创建

🌠 fork函数初识

在linux中fork函数是⾮常重要的函数,它从已存在进程中创建⼀个新进程。新进程为⼦进程,⽽原进程为⽗进程。

 #include <unistd.h>pid_t fork(void);
返回值:⾃进程中返回0,⽗进程返回⼦进程id,出错返回-1

进程调⽤fork,当控制转移到内核中的fork代码后,内核做:

  • 分配新的内存块和内核数据结构给⼦进程
  • 将⽗进程部分数据结构内容拷⻉⾄⼦进程
  • 添加⼦进程到系统进程列表当中
  • fork返回,开始调度器调度

在这里插入图片描述
当⼀个进程调⽤fork之后,就有两个⼆进制代码相同的进程。⽽且它们都运⾏到相同的地⽅。但每个进程都将可以开始它们⾃⼰的旅程,看如下程序。

在这里插入图片描述
这⾥看到了三⾏输出,⼀⾏before,两⾏after。进程43676先打印before消息,然后它有打印after。
另⼀个after消息有1398691打印的。注意到进程1398691没有打印before,为什么呢?如下图所⽰
在这里插入图片描述
所以,fork之前⽗进程独⽴执⾏,fork之后,⽗⼦两个执⾏流分别执⾏。注意,fork之后,谁先执⾏完
全由调度器决定。

🌉fork函数返回值

  • ⼦进程返回0
  • ⽗进程返回的是⼦进程的pid。

🌠 写时拷⻉

通常,⽗⼦代码共享,⽗⼦再不写⼊时,数据也是共享的,当任意⼀⽅试图写⼊,便以写时拷⻉的⽅式各⾃⼀份副本。具体⻅下图:
在这里插入图片描述
因为有写时拷⻉技术的存在,所以⽗⼦进程得以彻底分离离!完成了进程独⽴性的技术保证!

写时拷⻉,是⼀种延时申请技术,可以提⾼整机内存的使⽤率

🌉fork常规⽤法

  • ⼀个⽗进程希望复制⾃⼰,使⽗⼦进程同时执⾏不同的代码段。例如,⽗进程等待客⼾端请求,⽣成⼦进程来处理请求。
  • ⼀个进程要执⾏⼀个不同的程序。例如⼦进程从fork返回后,调⽤exec函数。

🌉fork调⽤失败的原因

  • 系统中有太多的进程
  • 实际⽤⼾的进程数超过了限制

🌠进程终⽌

进程终⽌的本质是释放系统资源,就是释放进程申请的相关内核数据结构和对应的数据和代码。

🌉进程退出场景

  1. 代码运⾏完毕,结果正确
  2. 代码运⾏完毕,结果不正确
  3. 代码异常终⽌

🌉进程常⻅退出⽅法

正常终⽌(可以通过 echo $? 查看进程退出码):

  1. 从main返回
  2. 调⽤exit
  3. _exit

异常退出:

  • ctrl+c 信号终⽌

🌉退出码

退出码(退出状态)可以告诉我们最后一次执行的命令的状态。在命令结束以后,我们可以知道命令是成功完成的还是以错误结束的。其基本思想是,程序返回退出代码0时表示执行成功,没有问题。

代码10以外的任何代码都被视为不成功。

Linux Shell 中的主要退出码 :

退出码解释
0命令成功执行
1通用错误代码
2命令(或参数)使用不当
126权限被拒绝(或)无法执行
127未找到命令,或PATH错误
128 + n命令被信号从外部终止,或遇到致命错误
130通过Ctrl + C或SIGINT终止(终止代码2或键盘中断)
143通过SIGTERM终止(默认终止)
255/ *退出码超过了0 - 255的范围,因此重新计算(LC3TT注:超过255后,用退出码取模)
  • 退出码0表示命令执行无误,这是完成命令的理想状态。
  • 退出码1我们也可以将其解释为“不被允许的操作”。例如在没有sudo权限的情况下使用yum;再例如除以0等操作也会返回错误码1,对应的命令为let a=1/ 0
  • 130 (SIGINT]或^c))和143([SIGTERM))等终止信号是非常典型的,它们属于128+n信号,其中n代表终止码。
  • 可以使用strerror函数来获取退出码对应的描述。

🌉_exit函数

#include <unistd.h>void _exit(int status);
参数:status 定义了进程的终⽌状态,⽗进程通过wait来获取该值

说明:虽然status是int,但是仅有低8位可以被⽗进程所⽤。所以_exit(-1)时,在终端执⾏$?发现返回值是255。

🌉exit函数

 #include <unistd.h>void exit(int status);

exit最后也会调⽤_exit,但在调⽤_exit之前,还做了其他⼯作:

  1. 执⾏⽤⼾通过atexit或on_exit定义的清理函数。
  2. 关闭所有打开的流,所有的缓存数据均被写⼊
  3. 调⽤_exit

在这里插入图片描述
实例:

int main()
{printf("hello");exit(0);
}
运⾏结果: [root @localhost linux] #./a.out
hello[root @localhost linux]#int main()
{printf("hello");_exit(0);
}
运⾏结果: 
[root @localhost linux] #./a.out
[root @localhost linux] #

🌉return退出

return是⼀种更常⻅的退出进程⽅法。执⾏returnn等同于执⾏exit(n),因为调⽤main的运⾏时函数会将main的返回值当做exit的参数。


🚩总结

请添加图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com