fork,vfork,system

原创 2012年07月11日 14:04:17

1.fork()函数

#include<unistd.h>

pid_t fork(void);

创建一个子进程。

正确返回:父进程中返回子进程的进程号;子进程中返回0;(返回两次,父进程和子进程中各返回一次)

错误返回:-1;(父进程中返回)

2.vfork()函数

#include<unistd.h>

pid_t vfork(void);

创建一个子进程,阻塞父进程。vfork创建新进程的主要目的在于用exec函数执行另外的程序。

返回情况同fork()函数。

fork,vfork区别:

(1)fork()的子进程拷贝父进程的数据段,代码段;vfork()的子进程与父进程共享数据段。

(2)fork()后父、子进程的执行顺序不确定;vfork()后,子进程先运行(阻塞父进程),在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才运行。

(3) vfork()保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程、 依赖于父进程的进一步动作,则会导致死锁。

注意1:主要是第3点难以理解,我理解是:在vfork()子进程执行的代码,必须调用execX函数或者以exit、_exit函数结束,否则会发生错误。(具体原因望大牛指点……在网上找了好多,没有人给予解答。)

注意2:vfork()后从子进程中返回,必须使用_exit()函数来返回,如果使用exit()或者return的时候,会关闭所有的IO,此时如果父进程再进行IO操作,就会出错。

实例:

#include <unistd.h>
#include <stdio.h>
 int main()
 {
     pid_t pid;
     int count = 0;
     pid = vfork();
     ++count;
     printf("count = %d\n",count);
     return 0;
 } 

如果是fork(),结果很容易知道,是:

count = 1

count = 1

是调用vfork()呢,结果出人意料的是:

count = 1

count = 2

count = 1

count = 2…… //直到进程号被分配完才会退出。

3.system函数

#include<stdlib.h>

int system(constchar *command);

执行一个shell命令。

我们直接看system函数的实现代码:

 int system(const char *cmd)
 {
 	pid_t pid;
 	int status;
 	if(cmd == NULL)
 	{
 		return 1;
 	}
 	if((pid = fork()) < 0)
 	{
 		status = -1;
 	}
 	else if(pid == 0)
 	{
 		execl("/bin/sh", "sh", "-c",cmd, (char*)0);
 		_exit(127);
 	}
 	else
 	{
 		while(waitpid(pid, &status, 0) < 0)
 		{
 			if(errno != EINTR)
 			{
 				status = -1;
 				break;
 			}
 		}
 	}
 	return status;
 } 
可见,system()函数调用fork()创建子进程,然后调用execl()函数覆盖子进程镜像去执行shell命令“cmd”,父进程一直在阻塞等待子进程的返回。

fork的一道面试题:

#include <unistd.h>
 #include <stdio.h>
 int main()
 {
 	int i;
 	for(i = 0; i < 2; ++i)
 	{
 		fork();
 		printf("-");
 	}
 	return 0;
 }

问打印多少“-”?

答案:在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区等。printf(“-”);把“-”放到了缓存中,并没有真正的输出,在fork的时候,缓存被复制到了子进程空间,所以,就多了两个,就成了8个,而不是6个。如果printf("-\n");有“\n”时,是每次刷新缓冲区,这样最后打印6个,因为标准输出遇到“\n”,或是EOF,或是缓中区满,或是文件描述符关闭,或是主动flush,或是程序退出,就会把数据刷出缓冲区。

求解:

不得不说vfork真的很蛋疼,一些现象我是实在理解不了,如下:

#include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 int createproc();
 int main()
 {
 	printf("main : pid = %d\n",getpid());
 	pid_t pid = createproc();
 	printf("in main : %d\n", pid);
 	exit(0);
 }
 int createproc()
 {
 	pid_t pid;
 	if((pid = vfork()) == 0)
 	{
 		printf("child proc:%d,id = %d\n", pid,getpid());
 		return pid;
 	}
 	else if(pid > 0)
 	{
 		printf("parent run, child pid = %d\n",pid);
 		return pid;
 	}
 	else 
 	  return -1;
 }

out:

main : pid = 3416

child proc:0,id = 3417

in main : 0

parent run, child pid = 3417

child proc:0,id = 3418

//最后一句理解不了,懂的人还望留言指点





Linux中fork,vfork和clone详解(区别与联系)

fork,vfork,cloneUnix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(...
  • gatieme
  • gatieme
  • 2016年05月15日 16:09
  • 15758

对fork,vfork 与exec的一些个人见解

转载来源http://blog.chinaunix.net/uid-20528014-id-4068931.html 作者:fireaxe_hq@hotmail.com 博客:fi...
  • yanxinrui0027
  • yanxinrui0027
  • 2016年06月07日 10:42
  • 1188

用return和exit结束fork和vfork创建的子进程的思考

fork和vfork的差别: 1、fork是创建一个子进程,并把父进程的内存数据copy到子进程中。 vfork是创建一个子进程,并和父进程的内存数据share一起。 2、vfork是这样的工作...
  • quzhilin123
  • quzhilin123
  • 2014年12月02日 11:03
  • 1601

uc笔记07---进程管理,PID,#ps,getxxxid,fork,vfork,system

1.    进程与程序     1) 进程就是运行中的程序。一个运行着的程序,     可能有多个进程。进程在操作系统中执行特定的任务。     2) 程序是存储在磁盘上,包含可执行机器指令和数据的...
  • wolfsun3
  • wolfsun3
  • 2015年09月30日 17:00
  • 391

fork与vfork、exec与system

比较fork与vfork之间的区别:都为创建一个子进程, 1、前者是将父进程的内存数据copy到子进程中,而后者则是共用父进程的内存数据 2、vfork:创建过子进程之后,阻塞父进程,当子进程调用...
  • u011467781
  • u011467781
  • 2015年01月17日 17:11
  • 705

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

  • 2010年11月04日 22:48
  • 782B
  • 下载

唯快不破:linux下 fork(),vfork(),clone()的用法及区别

fork,vfork,clone都是linux的系统调用,用来创建子进程的(确切说vfork创造出来的是线程)。 先介绍下进程必须的4要点: a.要有一段程序供该进程运行,就像一场...
  • zj6257
  • zj6257
  • 2018年01月02日 17:16
  • 75

【Linux/OS/Network】fork函数和vfork函数的分析及区别

fork and vfork
  • SuLiJuan66
  • SuLiJuan66
  • 2016年01月26日 15:38
  • 385

Linux进程创建:fork,vfork,exec,clone总结

Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息,包括数据段,代码段,堆栈段的地址,当前进程的环境变量,文件的描述符等,在创建进程...
  • xitongfengxi
  • xitongfengxi
  • 2016年07月22日 14:42
  • 460

fork与vfork(未完,正在每天更新中。。。。。)

一、fork系统调用 1、函数的声明: #include pid_t fork(void); 2、返回值:     fork函数调用一次,将会返回两次(返回给主进程为新创建的子...
  • shexinwei
  • shexinwei
  • 2011年11月29日 17:20
  • 992
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:fork,vfork,system
举报原因:
原因补充:

(最多只允许输入30个字)