#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = getpid();
fork();
printf("my pid is %d , current pro id %d\n",pid,getpid());
while(1);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = getpid();
fork();
if(pid == getpid()){
printf("this is father print\n");
}elae{
printf("this is child print,child pid = %d\n",getpid());
}
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid_t pid2;;
pid = getpid();
printf("before fork : pid = %d\n",pid);
fork();
pid2 = getpid();
printf("after fork :pid = %d\n",pid2);
if(pid == pid2){
printf("this is father print\n");
}else{
printf("this is child print,child pid = %d\n",getpid());
}
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
printf("father: id =%d\n",getpid());
pid = fork(); //fork返回值
if(pid >0){ //返回值大于0的整数,即父进程
printf("this is father print\n");
}else if(pid == 0){ //返回对于0,即为子进程
printf("this is child print,child pid = %d\n",getpid());
}
return 0;
}
fork()进程创建发生的事情
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int data = 10;
printf("father: id =%d\n",getpid());
pid = fork(); //拷贝代码,不改变的变量共享,改变的变量要拷贝,可以理解为将全部代码拷贝一份作为子进程来执行
if(pid >0){
printf("this is father print\n");
}else if(pid == 0){
printf("this is child print,child pid = %d\n",getpid());
data = data+100;
}
printf("data = %d\n",data);
return 0;
}
创建新进程的实际应用场景
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int data = 10;
while(1){
printf("please input a data:\n");
scanf("%d",&data);
if(data==1){
pid = fork();
if(pid >0){
}
else if((pid == 0)){
while(1){
printf("do net request,pid = %d\n",getpid());
sleep(3);
}
}
}
else{
printf("wait,do nothing\n");
}
}
return 0;
}
vfork()函的使用
vfork()与fork()有什么区别:
1.vfork直接使用父进程储存空间,不拷贝
2.vfork保证子进程先运行,子进程调用exit退出后父进程才执行
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid>0){
while(1){
printf("cnt = %d\n",cnt);
printf("this is father print,pid = %d\n",pid);
sleep(1); //睡眠1秒,防止刷屏
}
}
else if(pid ==0){
while(1){
printf("this is chilid print,pid = %d\n",pid);
sleep(1); //防止刷屏
cnt++;
if(cnt == 3){
exit(0); //退出子进程
}
}
}
return 0;
}
退出以及退出状态收集
正常退出
1.main函数调用return
2.进程调用exit(),标准c库
3.进程调用_exit()或者_Exit,属于系统调用
补充
1.进程最后一个线程返回
2.最后一个线程调用pthread_exit
异常退出
1.调用abort
2.当进程收到某些信号时,如crtl+c
3.最后一个线程对取消(cancellation)请求做出响应
在任一情况下,该终止进程的父进程都能用wait或waitpid函数取得其终止状态
父进程等待子进程退出并且收集子进程的退出状态,子进程退出状态不被收集,变成僵尸进程(僵死进程)
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid>0){
wait(&status); // wait阻塞,等待收集子进程资源,所以先执行子进程------敲重点
//waitpid(pid,&stats,WNOHANG); //挂起状态,子父一起运行,不阻塞,会出现僵尸进程
printf("child quit,child status = %d\n",WEXITSTATUS(status)); //需要用宏解析status
while(1){
printf("cnt = %d\n",cnt);
printf("this is father print,pid = %d\n",getpid());
sleep(1);
}
}
else if(pid == 0){
while(1){
printf("this is chilid print,pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}
孤儿进程:父进程如果不等待子进程退出,在子进程结束之前就结束了自己的“生命”,此时子进程叫做孤儿进程
Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程。
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
//孤儿进程
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid>0){
printf("this is father print,pid = %d\n",getpid());
}
else if(pid == 0){
while(1){
printf("this is chilid print,pid = %d,my father pid = %d\n",getpid(),getppid());
sleep(1);
cnt++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}