一、fork()函数原理
int main()
{
int pc;
pc=fork();
}
通过fork()语句创建子进程,其实就是将父进程的内容复制到子进程中,包括堆栈段、数据段等(包括把pc的值赋给子进程,所以子进程执行的入口不再是main(),而是pc=fork()这句话,当然,fork()这句指令是不执行的,子进程将fork()返回值赋给pc。而函数的返回值默认是0,所以在不执行fork()函数的情况下,子进程的pc=0)
二、子进程和父进程执行次序
1、(子进程先执行的情况)如果时间片很短,在父进程执行fork()语句时,时间片就用完了,由于fork()是原语,必须先将fork()执行完毕,才能切换时间片。当fork()语句执行完毕,父进程进入就绪队列,在这之前,子进程已经进入Ready队列。在就绪队列中,父进程在子进程之后,如果这个系统的调度算法是先来先服务,子进程就会在父进程之前执行。
2、(父进程先执行的情况)如果时间片很长,当父进程执行fork()语句之后,父进程还有时间片剩余,这样的话,就是父进程先执行,子进程后执行。
三、一个父进程创建两个
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
int main()
{
int pc,pd;
printf("%d\n",getpid());
pc=fork();
pd=fork();
if(pc > 0 && pd > 0)
{
printf("this is the father! my PID = %d\n",getpid());
}
if(pc==0 && pd >0)
{
printf("this is the first child! my PID = %d\n",getpid());
}
if(pc > 0 && pd == 0)
{
printf("this is the second child! my PID = %d\n",getpid());
}
if(pc ==0 && pd ==0)
{
printf("this is the grand child! my PID = %d\n",getpid());
}
}
如果是创建两个子进程,需要使用两个fork(),在第一个pc=fork()执行完毕之后,就有两个进程,即父进程和子进程。所以在执行第二个fork()时,就有两个进程中执行,因此,在两条fork()语句执行完毕,就有4个进程中运行。一个是父进程,两个子进程,一个孙子进程。
四、一个父进程创建两个子进程,第一个子进程执行"ls -l"指令,第二个子进程睡眠5s,之后退出,父进程在子进程都结束之后再结束。
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
int main()
{
int pc,pd;
printf("%d\n",getpid());
pc=fork();
pd=fork();
if(pc==0 && pd >0)
{
execlp("/bin/ls","/bin/ls","-l",NULL);
exit(1);
}
if(pc > 0 && pd == 0)
{
sleep(5);
exit(1);
}
if(pc > 0 && pd > 0)
{
printf("this is the father! my PID = %d\n",getpid());
wait(NULL);
exit(1);
}
}