fork、getpid、getppid函数

#include <unistd.h>

pid_t fork(void);

作用:创建一个子进程

到目前为止,我们可以直到两种创建进程的方法:1. 通过执行二进制文件来创建一个进程,如:./a.out  /bin/ls;2.通过fork函数来创建一个子进程

该函数没有形参,返回值类型为pid_t,为无符号整型。而进程的id为正整数。如果失败,则返回-1;如果成功,则由于父进程(调用fork函数的进程)创建了一个子进程,因此父进程与子进程都会有一个fork函数,一个fork函数变为了两个fork函数,从而就会有两个返回值,父进程的fork返回子进程的id,其值大于0,子进程的fork返回0,表示进程创建成功,因此可以根据返回值来判断哪个是父进程,哪个是子进程。

注意:注意返回值,不是fork函数能返回两个值,而是fork后,fork函数变为两个,父子需各自返回一个。

 

#include <sys/types.h>

#include <unistd.h>

pid_t getpid(void);

pid_t getppid(void);

作用:getpid返回当前进程(调用这一函数的进程)的ID;getppid返回当前进程的父进程的ID。都无形参。 这两个函数总是成功,因此返回值大于0。

//代码示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    pid_t pid;  //id为pid_t类型
    printf("xxxxxxxxxxx\n");    //这部分只是父进程执行,子进程虽然有这部分的代码,但是不执行,而是从创建处开始向下执行。

    pid = fork();   //此处产生了一个子进程
    if(pid == -1)
    {
        perror("fork");
        exit(1);
    }

    else if(pid == 0)   //如果是子进程
         printf("This is child process, and the pid = %u, the ppid = %u\n",getpid( ),getppid( ));
    else   //如果是父进程
    {
         printf("This is parent process, and the pid = %u, the ppid = %u\n",getpid( ),getppid( ));
         sleep(1);  // 保证子进程比父进程先结束
    }

    printf("yyyyyyyyyyyy, the pid = %u\n",getpid( ));  //父子进程都要执行这段代码

    return 0;
}

[root@localhost fork]# ./fork_test1

xxxxxxxxxxx   //只是父进程执行

This is parent process, and the pid = 14652, the ppid = 4199  //父进程也有父进程

yyyyyyyyyyyy, the pid = 14652  //父进程执行

This is child process, and the pid = 14653, the ppid = 14652  //子进程

yyyyyyyyyyyy, the pid = 14653  //子进程执行

由上可以看出,fork后的代码,父子进程都执行,fork前的代码只是父进程执行,虽然子进程也包含这段代码,但其只是从创建处开始执行。

[root@localhost fork]# ps aux | grep 4199   //查看父进程的父进程

root       4199  0.0  0.1 116352  3160 pts/0    Ss   Mar24   0:01 -bash

root      14722  0.0  0.0 112644   972 pts/0    S+   00:18   0:00 grep --color=auto 4199

可以看到,父进程的父进程中断为bash解释器,即终端进程,其在执行二进制文件时,也通过fork函数创建一个子进程来完成该二进制文件(./fork_test1)的执行,其原理与父进程创建子进程原理一样。

猜你喜欢

转载自blog.csdn.net/qq_33883085/article/details/88799822
今日推荐