天天看点

Linux多进程编程之 fork()&vfork()

关于进程,详见大学必修课《操作系统》

头文件 : #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;
}
           
Linux多进程编程之 fork()&amp;vfork()

  根据运行结果我们可以看出来,两个进程使用的是各自的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;
}
           
Linux多进程编程之 fork()&amp;vfork()

  根据运行结果我们可以看出来,两个进程使用的是共享的num