目录
一、fork函数
pid_t fork(void);
fork成功调用执行,返回两次
返回值为0,为子进程
返回值为非负数,为父进程
调用失败返回-1
fork函数会创建一个子进程来执行代码内容。
第一种代码示例:
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t pid;
pid=getpid();
printf("before pid is %d\n",pid);//输出fork前pid
pid_t pid2;//定义pid2
fork();//使用fork生成子进程
pid2=getpid();//获取当前pid号
printf("after pid2 is %d\n",pid2);//输出当前pid号
if(pid==pid2){//如果为父进程则输出父进程pid号
printf("this is father %d\n",pid2);
}else{//如果为子进程则输出子进程pid号
printf("this is child %d\n",pid2);
}
return 0;
}
可见,运行不仅执行了父进程同时也执行了子进程。
第二种代码示范:
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t pid;
printf("now pid is %d\n",getpid());
pid=fork();
//判断是否大于0,大于0则是父进程,等于0为子进程
if(pid>0){
printf("this is father,now pid is %d\n",getpid());
}else if(pid==0){
printf("this is child,now pid is %d\n",getpid());
}
return 0;
}
二、进程创建发生了什么事?
早期的Linux会对正文、初始化数据、堆、栈、命令行参数和环境变量以及文件、IO流进行拷贝。
现在的Linux会进行写时拷贝copy on write,比如变量a在子进程有改变值才会在子进程的地址空间拷贝一份a和修改a的值;子进程对a不发生改变,我们就对a进行共享。
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main ()
{
pid_t pid;
int a=0;
pid=fork();
if(pid>0){
printf("a value is %d\n",a);
}else if(pid ==0){
a=a+10;
printf("a value is %d\n",a);
}
return 0;
}