目录
1、概念:
fork函数从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
使用fork()要包含头文件:#include <unistd.h>
pid_t id = fork(void);
返回值:子进程中返回0,父进程返回子进程id,出错返回-1
进程调用fork,当控制转移到内核中的fork代码后执行以下操作:
1、分配新的内存块和内核数据结构给子进程2、将父进程部分数据结构内容拷贝至子进程3、添加子进程到系统进程列表当中4、fork返回,开始调度器调度
2、程序测试:
int main()
{
pid_t id = fork();
if(id == 0)
{
//child
printf("I am child, pid: %d, ppid: %d\n", getpid(),getppid());
sleep(1);
}
else if(id > 0)
{
printf("I am father, pid: %d\n", getpid());
sleep(1);
}
return 0;
}
由输出结果可见,子进程与父进程又不同的pid但是子进程的ppid就是父进程的pid。
3、写时拷贝:

4、fork常规用法:
1、一个进程希望创建一个子进程。使父子进程同时执行不同的代码段。
2、一个进程要执行另一个不同的进程,例如子进程从fork返回后调用exec函数。
5、fork失败的原因:
1、系统中有太多的进程
2、实际用户的进程数超过了限制
6、进程终止:
进程退出场景:
1、代码运行完毕,结果正确。
2、代码运行完毕,但结果不正确。
3、代码异常终止。
7、进程常用退出方法:
正常终止:(可以通过 echo $? 查看进程退出码)
1、从main的return返回
2、调用exit
3、调用_exit
exit实际上也是调用了_exit,exit退出前会冲刷缓冲,关闭流,如果缓冲区中有内容就会显示出来,但_exit不会。
异常退出:
ctrl+c退出
8、等待进程 :
1、wait函数:
#include<sys/types.h>
#include<sys/wait.h>
pid_t rid = wait(int*status);
2、waitpid函数:
pid_t rid = waitpid(pid_t pid, int *status, int options);
//案例
pid_t rid = waitpid(id, &status,0)//当options为0时,父进程是阻塞等待的方式
pid_t rid = waitpid(id, &status,WNOHANG)//当options为WHOHANG时,父进程是非阻塞等待的方式
pid=-1, 等待任一个子进程。与 wait 等效。pid>0. 等待其进程 ID 与 pid 相等的子进程。
WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status): 若 WIFEXITED 非零,提取子进程退出码。(查看进程的退出码)
WNOHANG: 若 pid 指定的子进程没有结束,则 waitpid() 函数返回 0 ,不予以等待。若正常结束,则返回该子进程的ID 。
本文详细介绍了fork()函数的概念、用法、常见场景,以及写时拷贝机制。涵盖了程序测试中fork的效果、子进程与父进程的关系,以及进程的正常终止与异常退出方式,如wait和waitpid函数的使用。
401

被折叠的 条评论
为什么被折叠?



