加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

linux中利用fork()函数创建两个子进程

(2012-09-10 20:58:16)
标签:

linux

双进程问题

最近在学习嵌入式linux,用的是华清远见的《嵌入式linux应用程序开发详解》这本书,同时又配合中嵌的视频教程,在做实验7.4.1时,发现自己把书中的源程序在虚拟机(RedHat 9.0)运行时发觉,我得到的结果跟书上给出的结果是不相符合。

源程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
//int i=0;
int main()
{
        pid_t child,child1,child2;


        int i=0;                                                                                                           
        child1=fork();
        child2=fork();                                                                                                                             
        if(child1==-1)
        {
                perror("child1 fork");
                exit(1);
        }
        else if(child1==0)
                {
                        printf("In child1: execute 'ls -l'\n");
                        printf("\nchild1: pid=%d,ppid=%d,i=%d\n\n",getpid(),getppid(),i++);
                        if(execlp("ls","ls","-l",NULL)<0)
                                perror("child1 execlp");
                }
                                                                                                                            
        if(child2==-1)
        {
                perror("child2 fork");
                exit(1);
        }
        else if(child2==0)

        {

                printf("In child2: sleep for 5 seconds and then exit\n");
                printf("\nchild2: pid=%d,ppid=%d,i=%d\n\n",getpid(),getppid(),i++);
                sleep(5);
                exit(0);
        }
        else
        {
                printf("\nIn father process: pid=%d\n\n",getpid());
                do
                {
                        child=waitpid(child2,NULL,WNOHANG);
                        if(child==0)
                        {
                                printf("The child2 process has not exited!\n");
                                sleep(1);
                        }
                }while(child==0);
                if(child==child2)
                        printf("Get child2\n");
                else
                        printf("Error occured!\n");
        }
}

运行结果如下:

In child2: sleep for 5 seconds and then exit
 
child2: pid=25809,ppid=25806,i=0
 
 
In father process: pid=25806
 
The child2 process has not exited!
In child1: execute 'ls -l'
 
child1: pid=25808,ppid=25807,i=0
 
total 88
-rwxr-xr-x    1 root     root        12016 Apr  6 19:19 1fork
In child1: execute 'ls -l'
 
child1: pid=25807,ppid=25806,i=0
 
total 88
-rwxr-xr-x    1 root     root        12016 Apr  6 19:19 1fork
-rw-r--r--    1 root     root          377 Apr  6 19:19 1fork.c
-rwxr-xr-x    1 root     root        13017 Apr  7 14:30 exc
-rw-r--r--    1 root     root         1067 Apr  7 12:07 exc.c
-rwxr-xr-x    1 root     root        12015 Apr  6 17:09 fork
-rw-r--r--    1 root     root          402 Apr  6 17:09 fork.c
-rwxr-xr-x    1 root     root        12088 Apr  2 14:17 open
-rw-r--r--    1 root     root          435 Apr  6 16:53 open.c
-rw-r--r--    1 root     root         1702 Apr  7 11:01 result.txt
-rwxr-xr-x    1 root     root        11739 Apr  7 12:43 testfork
-rw-r--r--    1 root     root          218 Apr  7 12:43 testfork.c
-rw-r--r--    1 root     root          377 Apr  6 19:19 1fork.c
-rwxr-xr-x    1 root     root        13017 Apr  7 14:30 exc
-rw-r--r--    1 root     root         1067 Apr  7 12:07 exc.c
-rwxr-xr-x    1 root     root        12015 Apr  6 17:09 fork
-rw-r--r--    1 root     root          402 Apr  6 17:09 fork.c
-rwxr-xr-x    1 root     root        12088 Apr  2 14:17 open
-rw-r--r--    1 root     root          435 Apr  6 16:53 open.c
-rw-r--r--    1 root     root         1702 Apr  7 11:01 result.txt
-rwxr-xr-x    1 root     root        11739 Apr  7 12:43 testfork
-rw-r--r--    1 root     root          218 Apr  7 12:43 testfork.c
The child2 process has not exited!
The child2 process has not exited!
The child2 process has not exited!
The child2 process has not exited!
Get child2
       其中子进程child1运行了两次。现在这个结果也没有弄清楚,有时个child2先运行,有时候child1先运行,大部分情况是两个子进程不是一次执行完的,从结果来看是交叉运行的。这可能跟linux的调度算法有关,而linux又不止采用了一种调度算法,所以这个也没有敢深究。希望有大侠能帮我解惑。

源程序创建了三个子进程,如下图所示,下面这段代码在子子进程1中先运行一次,接着又在子进程1 中又运行了一次,所以第一次打印的结果中当前进程ID,都较大的原因比如:child1: pid=25808,ppid=25807,i=0;child1:pid=25808,ppid=25807,i=0
其中父进程ID为25806;子进程1的ID为25807;子子进程1的ID为25808;子进程2的ID为25809;而下面的代码先在pid=25808的子子进程1中运行一次,又在pid=25807的子进程1中又运行了一次!

http://img855.ph.126.net/3DlsZJDXRiS4qRkfcg8lZg==/634726072483670861.jpg

child2=fork();
if(child1==-1)
{
perror("child1 fork");
exit(1);
}
else if(child1==0)
{
printf("In child1: execute 'ls -l'\n");
printf("\nchild1: pid=%d,ppid=%d,i=%d\n\n",getpid(),getppid(),i++);
if(execlp("ls","ls","-l",NULL)<0)
perror("child1 execlp");
}

       在这里只是怀疑fork()函数创建子进程有误,搜了几个精品的帖子对fork()函数的执行有了认识,才知道书中的源程序是错的,不止创建了两个子进程,也不知道书中给出的结果他们是从哪里弄来的,这本书中错误太多了。fork()函数以后的代码,父子进程是共享的,不过它们不在同一个空间,而是分开的、独立的。fork()函数最好不要用在if   else语句中,或者使用时要特别小心。

========================================================================

       真正创建两个子进程的代码是:

#include <stdio.h>
int main()
{
         int pid;
                                                                                                                            
         pid=fork();
         if(pid==0)
                printf("I'm child1 process,my pid is %d.\n",getpid());
                                                                                                                            
         else if(pid>0)
         {

                
                 printf("I'm father process,my pid is %d.\n",getpid());
                 pid=fork();
                 if(pid==0)
                        printf("I'm child2 process,my pid is %d.\n",getpid());
                 else if(pid>0)
                        printf("I'm father process,my pid is %d.\n",getpid());
                 else
                        printf("fork() error.\n");
         }
         else printf("fork() error.\n");
}
=============================================================================

下面test2.c这个程序用fork()函数创建了三个子进程,共四个进程:

 

#include <stdio.h>
main()
{
        int pid; 
        pid=fork();
        if(pid==0)               printf("I'm child process,my pid is %d.\n",getpid());
        else if(pid>0)          printf("I'm father process,my pid is %d.\n",getpid());
        else                        printf("fork() error.\n");
        pid=fork();
        if(pid==0)               printf("I'm child process,my pid is %d.\n",getpid()); 
        else if(pid>0)          printf("I'm father process,my pid is %d.\n",getpid());
        else                        printf("fork() error.\n");
}
--------------------------------------------------------------------------------------------------------

另外还有一个有趣的程序(猜猜输出的是什么,如果换成后面的几句又输出的是什么):

#include <stdio.h>
int main()
{
        printf("Hello");         // fflush(0);         // fflush(stdout);            //printf("Hello\n");
        fork();
        return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有