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
//最后一句理解不了,懂的人还望留言指点