旭++

张旭的C++学习笔记
posts - 5, comments - 8, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

linux fork函数学习

Posted on 2007-12-02 15:20 张旭 阅读(10546) 评论(7)  编辑 收藏 引用
在编写socket ftp之前,我对fork函数进行了学习。
先看这段范例代码:
#include <unistd.h>


#include 
<sys/types.h>


main () 





   pid_t pid; 


        pid
=fork(); 


        
if (pid < 0


                printf(
"error in fork!"); 


        
else if (pid == 0


                printf(
"i am the child process, my process id is %dn",getpid()); 


        
else 


                printf(
"i am the parent process, my process id is %dn",getpid()); 



}
 

这段代码写了一个使用fork函数创建子进程,父子进程同时运行而产生交错的,不一样的运行结果。
运行结果如下:
[root@localhost c]# ./a.out
i am the child process, my process id is 4286
i am the parent process, my process id is 4285 
      fork在英文中是叉子,分叉的意思,在函数fork中,取后面的意思。很形象的表示程序从这里分叉,fork函数创建了子进程,子进程和父进程同时(其实是cpu分时处理)开始运行分叉之后的程序。
      我把程序改写了一下: 

 

#include <unistd.h>
#include 
<sys/types.h>
main()
{
        pid_t pid;
        printf(
"\n[%d]not fork pid=%d\n",getpid(),pid);
        pid
=fork();
        printf(
"\n[%d]forked pid=%d\n",getpid(),pid);
        
if(pid<0)
        
{
                printf(
"error in fork!\n");
                getchar();
                exit(
1);
        }

        
else if(pid==0)
                printf(
"\n[%d]in child process,p_id=%d\n",getpid(),getpid());
        
else
        
{
                printf(
"\n[%d]in parent process,my pid=%d\n",getpid(),pid);
                printf(
"\n[%d]in parent process,my getpid=%d\n",getpid(),getpid());

        }

}


程序运行结果如下:
[hardy@localhost fork]$ ./fork

[3819]not fork

[3820]forked pid=0

[3820]in child process,p_id=3820

[3819]forked pid=3820

[3819]in parent process,my pid=3820

[3819]in parent process,my getpid=3819

可以清楚的看到 not fork只打印了一次,其中[3819]是父进程的进程号,创建fork以后,fork函数返回给父进程的值pid是子进程的进程号[3820],而在子进程中,pid值为零。也就是说子进程中,pid被置零。

引用网上一位网友的解释“其实就相当于链表,进程形成了链表,父进程pid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其pid为0. 

下面有一个很有意思的程序:
#include <sys/types.h>
#include 
<unistd.h>

int main()
{
        
int i;
        
for( i= 0; i< 3; i++)
        
{
                
int pid= fork();
                
if(pid== 0)
                
{
                        printf(
"son\n");
                }

                
else
                
{
                        printf(
"father\n");
                }

        }

        
return 0;
}


大家想想看最后将出现几个son 几个father呢?








对一下答案吧:
[hardy@localhost fork]$ ./fork
father
son
son
son
father
father
son
father
son
son
father
father
son
father

总共7个son7个father。你答对了么?

这道题需要在纸上画画才好理解
for            i=0         1           2
               father     father     father
                                           son
                              son       father
                                            son
               son       father        father
                                             son
                              son         father
                                             son
其中每一行分别代表一个进程的运行打印结果。
当产生子进程的时刻,子进程打印son,当子进程调用fork的生成子子进程,他就提升为father。
总结来说,father永远打印father,son在fork之前是son,fork之后就为father,同时生成新的son。
这个比喻就像真正的父子,孩子长大了生了小孩,孩子就成了父亲。而父亲永远是父亲。

Feedback

# re: linux fork函数学习  回复  更多评论   

2008-08-06 12:55 by zcc
xhu,2舍的张旭?不会真的是你吧?呵呵,我搜索fork()的时候搜到了这里,如果真你是你该知道我是哪个了吧,呵呵,我是zcc

# re: linux fork函数学习  回复  更多评论   

2008-08-06 13:00 by 张旭
@zcc
抱歉,我想不起来你是谁。可能认错了吧。

# re: linux fork函数学习  回复  更多评论   

2009-02-21 18:39 by
很强大。。。

# re: linux fork函数学习  回复  更多评论   

2012-01-06 17:21 by er
gcc怎么写

# re: linux fork函数学习[未登录]  回复  更多评论   

2012-04-10 20:56 by noname
good!

# re: linux fork函数学习[未登录]  回复  更多评论   

2012-04-10 20:58 by noname
请问最后一个程序,是不是father和son的输出没有规律,第一组是father和son的组合,第二组是两个father和两个son的组合,最后一组是四个father和四个son的组合就是了吗?

# re: linux fork函数学习  回复  更多评论   

2012-08-23 18:55 by 过客
你知道fork后系统是怎么分清那个该子进程运行哪些是父进程运行吗?

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理