关于进程,详见大学必修课《操作系统》
头文件 : #include<unistd.h>
函数: pid_t fork(void); // pid_t 是 int 类型,用来表示子进程的 pid 是一个大于0 的整数
pid_t pid=fork();//在父进程调用fork()函数
//若成功调用,一次返回两个值,对于父进程而言,返回的是子进程的pid >0,对于子进程而言,返回的是0
//可以根据 pid 来判断当前在哪个进程
//若 pid == -1 则表示fork()函数失败未能创建新的进程
//若 pid == 0 表示当前进程为子进程
//若 pid > 0 表示当前进程为父进程
内核根据父进程复制出一个子进程,父进程和子进程的PCB信息相同,用户态代码和数据也相同。
即子进程将会复制fork()函数以下的所有指令,指令与数据完全独立于父进程,与父进程只有 pid不同
getpid()函数 获取当前进程的 pid
getppid()函数 获取当前进程的父进程的 pid
子进程可以使用getppid()获取父进程的 pid,父进程无法得知子进程的 pid
子进程与父进程的执行顺序随机,不知那一个优先运行和结束
sleep(int x) 函数 使当前进程挂起x秒,即x秒后继续执行,可以控制子进程和父进程的结束顺序
fork()程序示例
creatChild.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int num = 3;
pid_t pid = fork();
printf("hello\n");//会被两个进程执行
if(pid==-1){
perror("fork error");//输出错误
exit(0);
}
else if (pid>0){
sleep(2);//让子进程先执行,原因后续会讲
num++;
printf("I am parent! num is %d\n",num);
printf("My pid is %d\n",getpid());
}
else {
num--;
printf("I am child! num is %d\n",num);
printf("My parent's pid is %d\n",getppid());
printf("My pid is %d\n",getpid());
}
return 0;
}
根据运行结果我们可以看出来,两个进程使用的是各自的num
pid_t vfork(void); //与fork作用相同,但是:
1、vfork创建的子进程和父进程之间是共享地址空间的,即数据不独立,是共享的
2、vfork()创建的子进程必须调用 exit()或者exec()类函数才能停止,否则子进程不会结束,会发生段错误
3、子进程一定会优先于父进程之前执行,即使父进程被sleep挂起,子进程仍然优先执行
vfork()程序示例
vcreatChild.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int num = 3;
pid_t pid = vfork();
printf("hello\n");//会被两个进程执行
if(pid==-1){
perror("fork error");//输出错误
exit(0);
}
else if (pid>0){
num++;
printf("I am parent! num is %d\n",num);
printf("My pid is %d\n",getpid());
}
else {
sleep(3);//即使是让子进程挂起,仍然是子进程先执行
num--;
printf("I am child! num is %d\n",num);
printf("My parent's pid is %d\n",getppid());
printf("My pid is %d\n",getpid());
exit(0);//vfork()专属,可以不加试试
}
return 0;
}
根据运行结果我们可以看出来,两个进程使用的是共享的num