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

2019-07-13 06:57发布

  对于fork函数: 子进程只继承父进程的文件描述表,不继承但共享文件表项和i-node 父进程创建一个子进程之后,文件表项中的引用计数加1变为2,当父进程作close操作之后计数器减1,子进程还是可以使用文件表项,只有计数器减到0的时候才会释放该文件表项   fork函数测试: #include #include #include #include #include #include #include #include #include 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 "); /* 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 ", getpid(), glob, var); // _exit(0); /* child terminates */ } else { //父进程 } //父子进程都要执行 fprintf(fp, "pid = %d, glob = %d, var = %d ", getpid(), glob, var); //fprintf(fp, "s: %s, pid : %d ", s, getpid()); close(fp); close(fd); sleep(1); exit(0); }  测试结果: 使用fork函数的缓存区会复制到子进程中,在父子进程都需要执行 //父子进程都要执行 fprintf(fp, "pid = %d, glob = %d, var = %d ", getpid(), glob, var); 的时候父子进程中都含有上面: fprintf(fp, "s: %s, pid : %d", s, getpid()); //实际上是先写到缓存中去的 fp缓存区中的内容,因此在执行的时候父子进程都能将  hello andrew输出到自己的缓存中去,一旦程序结束父子进程缓存区中的内容都会写入fp所指向的文件;   vfork函数测试: #include #include #include #include #include #include #include #include #include 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 "); /* 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 ", getpid(), glob, var); // _exit(0); /* child terminates */ } else { //父进程 } //父子进程都要执行 fprintf(fp, "pid = %d, glob = %d, var = %d ", getpid(), glob, var); //fprintf(fp, "s: %s, pid : %d ", s, getpid()); close(fp); close(fd); sleep(1); exit(0); } 测试结果: 在使用vfork的时候,可以看到,只有一个 hello andrew输出,以内vfork函数是部位子进程创建单独的分区的而是和父进程共用一个,一旦子进程将缓存区中的内容输出,那么另一位缓存区中也不会在有内容,因为两者缓存区是相同的; 总结:vfork创建的子进程,子进程会先运行并且=不会复制父进程的内存空间。