在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程
进程调用fork,当控制转移到内核中的fork代码时,内核完成以下工作:
#include
#include
#include
int main()
{
pid_t pid;
printf("Before: pid is %d\n", getpid());
if ((pid = fork()) == -1)
perror("fork()"), exit(1);
printf("After:pid is %d, fork return %d\n", getpid(), pid);
sleep(1);
return 0;
}
运行结果:
结论:fork之前父进程独立执行,fork之后,父子两个执行流分别执行。注意,fork之后,谁先执行完全由调度器决定。
子进程返回0;父进程返回子进程的PID
1. 子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。2. 进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。3. 父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。4. 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息
进程等待的方法
wait方法
#include
#include
#include
#include
#include
int main()
{
pid_t pid;
if ((pid = fork()) == -1)
perror("fork"), exit(1);
if (pid == 0)
{
sleep(20);
exit(10);
}
else
{
int st;
int ret = wait(&st);
if (ret > 0 && (st & 0X7F) == 0)
{ // 正常退出
printf("child exit code:%d\n", (st >> 8) & 0XFF);
}
else if (ret > 0)
{ // 异常退出
printf("sig code : %d\n", st & 0X7F);
}
}
return 0;
}
运行结果:
等待20s后
int main()
{
pid_t pid;
pid = fork();
if (pid < 0)
{
printf("%s fork error\n", __FUNCTION__);
return 1;
}
else if (pid == 0)
{ // child
printf("child is run, pid is : %d\n", getpid());
sleep(5);
exit(257);
}
else
{
int status = 0;
pid_t ret = waitpid(-1, &status, 0); // 阻塞式等待,等待5S
printf("this is test for wait\n");
if (WIFEXITED(status) && ret == pid)
{
printf("wait child 5s success, child return code is :%d.\n", WEXITSTATUS(status));
}
else
{
printf("wait child failed, return.\n");
return 1;
}
}
return 0;
}
1.代码运行完毕,结果正确;
2.代码运行完毕,结果不正确
3.代码异常终止
1. 从main返回
2.调用exit
3.调用 _exit
_exit函数
CTRL+C或者CTRL+\ 信号终止(实际是想进程发送了终止进程的信号)