Linux—— 进程管理核心操作与原理总结(一)
Linux——进程管理核心操作与原理总结(二)-CSDN博客
https://blog.csdn.net/wy_05136/article/details/160186035?sharetype=blogdetail&sharerId=160186035&sharerefer=PC&sharesource=wy_05136&spm=1011.2480.3001.8118
一、进程退出:exit() VS _exit()
| exit() | _exit() | |
| 类型 | C标准库函数 | Unix系统调用函数 |
| 作用 | 结束当前进程 | 结束当前进程,但是会将缓冲区内容清空 |
| 核心行为 |
会执行用户的资源清理操作,再调用内核级别的进程终止逻辑。 执行步骤: 1.执行用户注册的"退出处理函数" 2.刷新并关闭标准I/O缓冲区(把缓冲区内容强制刷新到终端或文件中) 3.清理进程的私有资源 4.调用_exit()触发内核回收 |
直接出发内核回收,会跳过所有的用户态操作,直接通知内核结束进程。 不执行"退出处理函数";不执行刷新标准I/O缓冲区。 |
| 标准I/O缓冲区 | 强制刷新并关闭 | 不刷新,直接丢弃数据 |
| 用法 |
1.普通单进程程序,优先使用exit() 2.多进程程序(父/子进程),子进程优先使用_exit(),避免干扰父进程的用户态资源,父进程使用eixt() |
|
二、printf函数输出问题
printf函数不会直接将数据输出到屏幕,而是先放到缓冲区中;只有满足以下情况,才会输出到屏幕。
(1)缓冲区满
(2)强制刷新缓冲区:调用fflush(stdout)(输出到屏幕)或者fflush(文件指针)(输出到文件)
(3)进程结束
(4)遇到换行符\n
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("hello");
//fflush(stdout);
/*
1.若执行此语句,则会强制刷新缓冲区,运行结果:直接输出hello
2.若不执行语句,运行结果:等进程结束后再输出hello
*/
sleep(3);
exit(0);
}
三、主函数参数介绍
int main( int argc, char* argv[], char* envp[])
argc:参数个数
argv:参数内容
envp:环境变量

四、复制进程 fork()
fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。
1.头文件:<unistd.h>
2.函数原型:pid_t fork(void);
3.函数返回类型:pid_t ,实质是 int 类型
4.返回值:有三种返回情况
(1)在父进程中,返回子进程的PID(正整数),用于父进程的识别和子进程的管理。
(2)在子进程中,PID的返回值是0,用于确认子进程的身份。
(3)如果返回-1,表示fork失败;失败原因:内存不足 或者 系统进程数达到上限;设置错误原因给到系统全局变量errorno,表示错误原因。
注意:
1.子进程会完全复制父进程的所有内容(包括缓冲区、变量、代码段);
2.父子进程独立运行,执行顺序由操作系统调度决定。
五、僵死进程 & 孤儿进程
1.僵死进程
子进程先于父进程结束,父进程没有获取子进程的退出码,子进程会变成僵死进程。
defunct表示该进程成为僵死进程。

2.如何处理僵死进程?
父进程通过调用wait()完成。
wait():让父进程等待子进程结束,然后获取子进程退出码,避免僵死进程
exit():让进程退出,参数为该进程的退出码
退出码是以二进制形式存储的,如何获取十进制退出码呢?
方法一:右移8位用%d打印
方法二:使用宏函数
WIFEXITED:判断进程是否正常退出,返回值为true或false
WEXITSTATUS:获取进程的正常退出码

3.孤儿进程
父进程先于子进程结束,子进程会变成孤儿进程,从而被进程资源管理器接管后继续运行。

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)