linux中fork()函数与vfork()函数的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/andrewgithub/article/details/82077818

对于fork函数:

子进程只继承父进程的文件描述表,不继承但共享文件表项和i-node

父进程创建一个子进程之后,文件表项中的引用计数加1变为2,当父进程作close操作之后计数器减1,子进程还是可以使用文件表项,只有计数器减到0的时候才会释放该文件表项

fork函数测试:

#include <unistd.h>  
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>




int		glob = 6;		/* external variable in initialized data */

int
main(void)
{
	int		var;		/* automatic variable on the stack */
	pid_t	pid;

	var = 88;
	printf("before vfork\n");	/* we don't flush stdio */
	FILE *fp = fopen("s.txt", "w");
	int fd = open("s_fd.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG);
	char *s = "hello andrew";
	ssize_t size = strlen(s) * sizeof(char);

	//标准IO函数带缓存功能-->全缓存
	fprintf(fp, "s: %s, pid : %d", s, getpid());  //实际上是先写到缓存中去的
	//缓存没有满程序没有结束,信息就会一直停留在缓存中
	//内核提供的IO系统调用(不带缓存)
	write(fd, s, size);//直接写入文件

	if ((pid = fork()) < 0) {
		perror("vfork error");
	} else if (pid == 0) {		/* child */
		glob++;					/* modify parent's variables */
		var++;
			//fprintf(fp, "pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
	//	_exit(0);				/* child terminates */
	}
	else
	{
		//父进程

	}
	//父子进程都要执行
	fprintf(fp, "pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
	//fprintf(fp, "s: %s, pid : %d\n", s, getpid()); 

        close(fp);
        close(fd);
	
	sleep(1);	
	exit(0);
}

 测试结果:

使用fork函数的缓存区会复制到子进程中,在父子进程都需要执行

//父子进程都要执行
	fprintf(fp, "pid = %d, glob = %d, var = %d\n", getpid(), glob, var);

的时候父子进程中都含有上面:

fprintf(fp, "s: %s, pid : %d", s, getpid());  //实际上是先写到缓存中去的

fp缓存区中的内容,因此在执行的时候父子进程都能将  hello andrew输出到自己的缓存中去,一旦程序结束父子进程缓存区中的内容都会写入fp所指向的文件;

vfork函数测试:

#include <unistd.h>  
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>




int		glob = 6;		/* external variable in initialized data */

int
main(void)
{
	int		var;		/* automatic variable on the stack */
	pid_t	pid;

	var = 88;
	printf("before vfork\n");	/* we don't flush stdio */
	FILE *fp = fopen("s.txt", "w");
	int fd = open("s_fd.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG);
	char *s = "hello andrew";
	ssize_t size = strlen(s) * sizeof(char);

	//标准IO函数带缓存功能-->全缓存
	fprintf(fp, "s: %s, pid : %d", s, getpid());  //实际上是先写到缓存中去的
	//缓存没有满程序没有结束,信息就会一直停留在缓存中
	//内核提供的IO系统调用(不带缓存)
	write(fd, s, size);//直接写入文件

	if ((pid = vfork()) < 0) {   //注意这里使用的是vfork函数
		perror("vfork error");
	} else if (pid == 0) {		/* child */
		glob++;					/* modify parent's variables */
		var++;
			//fprintf(fp, "pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
	//	_exit(0);				/* child terminates */
	}
	else
	{
		//父进程

	}
	//父子进程都要执行
	fprintf(fp, "pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
	//fprintf(fp, "s: %s, pid : %d\n", s, getpid()); 
	
        close(fp);
        close(fd);
	sleep(1);	
	exit(0);
}

测试结果:

在使用vfork的时候,可以看到,只有一个 hello andrew输出,以内vfork函数是部位子进程创建单独的分区的而是和父进程共用一个,一旦子进程将缓存区中的内容输出,那么另一位缓存区中也不会在有内容,因为两者缓存区是相同的;

总结:vfork创建的子进程,子进程会先运行并且=不会复制父进程的内存空间。

猜你喜欢

转载自blog.csdn.net/andrewgithub/article/details/82077818