今天,师兄问我一个问题说:小涛啊,创建两个进程太简单了,怎么创建多个进程呢?我说那还不容易,看下边代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | int main()
{
pid_t pid[2];
int i;
printf ( "This is %d\n" ,getpid());
for (i = 0;i < 2;i++ ){
if ((pid[0] = fork()) < 0){
printf ( "Fork() Error!" );
exit (-1);
}
if (pid[0] == 0)
printf ( "This is parent %d,child is %d\n" ,getppid(),getpid());
else
wait(5);
}
return 0;
}
|
好,这段代码还是挺简单的,我们的意思是:主线程通过循环创建2个子进程,这时系统中的总进程数应该是3,看看输出结果吧:
这个结果图看的效果不好,我们看个直接点的:
这下你明白了吧,问题没有想象中的那样简单,父进程现在标号为1的循环中创了一个子进程,然后第二次循环,前边的两个线程个创建一个子进程,这时明显系统中有四个进程,还是不懂?在下边的时序图吧:
这下你应该明白了吧,好了问题知道了,怎么解决,方法有二;
方法一:直接看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | void createsubprocess( int num)
{
pid_t pid;
int i;
for (i=0;i<num;i++)
{
pid=fork();
if (pid==0||pid==-1)
{
break ;
}
}
if (pid==-1)
{
perror ( "fail to fork!\n" );
exit (1);
}
else if (pid==0)
{
printf ( "子进程id=%d,其对应的父进程id=%d\n" ,getpid(),getppid());
exit (0);
}
else
{
printf ( "父进程id=%d\n" ,getpid());
exit (0);
}
}
|
这种方法的关键就在于每次循环时,如果发现是子进程就直接从创建子进程的循环中跳出来,不让你进入循环,这样就保证了每次只有父进程来做循环创建子进程的工作。
方法二:直接看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | void createsubprocess( int num, int max)
{
if (num>=max) return ;
pid=fork();
if (pid<0)
{
perror ( "fork error!\n" );
exit (1);
}
else if (pid==0)
{
sleep(3);
printf ( "子进程id=%d,父进程id=%d\n" ,getpid(),getppid());
}
else
{
num++;
if (num==1) printf ( "父进程id=%d\n" ,getpid());
if (num<max)createsubprocess(num,max);
sleep(5);
}
}
|
这里的关键在于递归操作,只有父进程才进入递归创建子进程,子进程不进行这样的操作。