fork函数用于创建新进程,而且有一个很有意思的特性需要注意。

下面的例子来自《linux c软件工程师实用教程》一书:

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
    pid_t result;
    result=fork();
    int rt;
    if(result==-1)
    {
        perror("failed to create process/n");
        return 1;
    }
    else if(result==0)
    {
        printf("return:%d,this is a subprocess. pid=%d, ppid=%d/n",result,getpid(),getppid());
        rt=system("ls -l 6.*");       
        printf("return:%d/n",result);
    }
    else
    {       
        printf("return:%d,this is a parent process. pid=%d, ppid=%d/n",result,getpid(),getppid());
        rt=system("ping www.baidu.com");   
    }
}

执行的结果如下:

yaojun@linux-zv38:~/programs/linuxc> gcc 6.4.c -o 6.4
yaojun@linux-zv38:~/programs/linuxc> 6.4


return:0,this is a subprocess. pid=13751, ppid=13750
-rwxr-xr-x 1 yaojun users 10870 2009-06-20 00:45 6.2
-rw-r--r-- 1 yaojun users   246 2009-06-20 00:45 6.2.c
-rw-r--r-- 1 yaojun users   244 2009-06-20 00:44 6.2.c~
-rwxr-xr-x 1 yaojun users 10828 2009-06-20 01:05 6.3
-rw-r--r-- 1 yaojun users   182 2009-06-20 01:04 6.3.c
-rw-r--r-- 1 yaojun users   182 2009-06-20 01:04 6.3.c~
-rwxr-xr-x 1 yaojun users 10978 2009-06-21 00:29 6.4
-rw-r--r-- 1 yaojun users   509 2009-06-21 00:29 6.4.c
-rw-r--r-- 1 yaojun users   539 2009-06-21 00:28 6.4.c~
return:13751,this is a parent process. pid=13750, ppid=13691
PING www.a.shifen.com (121.14.88.14) 56(84) bytes of data.
64 bytes from 121.14.88.14: icmp_seq=1 ttl=56 time=11.9 ms
64 bytes from 121.14.88.14: icmp_seq=2 ttl=56 time=11.5 ms
64 bytes from 121.14.88.14: icmp_seq=3 ttl=56 time=12.9 ms
(...)按ctrl+z结束ping程序。

 

可以看到程序不仅执行了result==0 时的情况,也执行了else 时的情况。咋看有点莫名其妙,其实这是由于fork产生的新进程将和主进程一起执行fork()以后的代码。这也是程序中放入了sleep(10)的原因,否则屏幕显示上就会交错出现ls和ping的结果。一般情况下,用fork产生新进程后,用exec函数族来执行其他程序。

详细说明可参考下面的文档:

 

26.2 Process Creation Concepts
==============================

This section gives an overview of processes and of the steps involved in
creating a process and making it run another program.

   Each process is named by a "process ID" number.  A unique process ID
is allocated to each process when it is created.  The "lifetime" of a
process ends when its termination is reported to its parent process; at
that time, all of the process resources, including its process ID, are
freed.

   Processes are created with the `fork' system call (so the operation
of creating a new process is sometimes called "forking" a process).
The "child process" created by `fork' is a copy of the original "parent
process", except that it has its own process ID.

   After forking a child process, both the parent and child processes
continue to execute normally.  If you want your program to wait for a
child process to finish executing before continuing, you must do this
explicitly after the fork operation, by calling `wait' or `waitpid'
(*note Process Completion::).  These functions give you limited
information about why the child terminated--for example, its exit
status code.

   A newly forked child process continues to execute the same program as
its parent process, at the point where the `fork' call returns.  You
can use the return value from `fork' to tell whether the program is
running in the parent process or the child.

   Having several processes run the same program is only occasionally
useful.  But the child can execute another program using one of the
`exec' functions; see *note Executing a File::.  The program that the
process is executing is called its "process image".  Starting execution
of a new program causes the process to forget all about its previous
process image; when the new program exits, the process exits too,
instead of returning to the previous process image.

Logo

更多推荐