目录

  • 基础API
  • fork
  • wait与waitpid
  • getpid与getppid
  • getuid与geteuid
  • getgid与getegid
  • 实例程序
  • 全局变量的共享问题
  • 孤儿进程
  • 僵尸进程

基础API

fork

头文件: #include <unistd.h>

pid_t fork(void); 创建一个子进程

pid_t类型表示进程ID, 但为了表示-1, 它是有符号整型. 0不是有效进程ID, init最小为1

返回值:
  失败: -1
  成功: 通过返回值判断父子进程. (1) 父进程返回子进程的ID(非负值); (2) 子进程返回 0

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

wait与waitpid

头文件:

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);阻塞函数调用一次回收一个子进程资源
返回值:
  -1: 回收失败, 已经没有子进程了
  >0: 回收是子进程对应的pid
参数:
  status: 传出参数, 用于判断子进程终止原因. 可使用下面三组宏函数判断终止原因
  WIFEXITED(status)非0 --> 进程正常退出: return; exit;
    WEXITSTATUS(status) 进一步获取进程退出状态
  WIFSIGNALED(status)非0 --> 进程异常终止
    WTERMSIG(status) 取得使进程终止的那个信号的编号
  WIFSTOPPED(status)非0 --> 进程处于暂停状态
    WSTOPSIG(status)取得使进程暂停的那个信号的编号
    WIFCONTINUED(status)为真, 进程暂停后已经继续运行

pid_t waitpid(pid_t pid, int *status, int options); 一次只回收一个进程
参数:
  pid > 0: 某个子进程的pid
  pid == -1: 回收所有的子进程, 循环回收
  pid == 0: 回收当前进程组的所有子进程
  pid < -1: 回收当前进程组内的任意子进程, 取翻(加减号)
  status: 子进程的退出状态, 用法同wait函数
  opttions: 0, 阻塞; WNOHANG, 非阻塞
返回值:
  -1: 回收失败, 没有子进程
  >0: 被回收的子进程
  =0: 参3为WNOHANG, 且子进程正在运行

getpid与getppid

头文件:

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

pid_t getpid(void); 获取当前进程的ID

pid_t getppid(void); 获取当前进程的父ID

getuid与geteuid

头文件:

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

uid_t getuid(void); 获取当前进程实际用户ID

uid_t geteuid(void); 获取当前用户有效用户ID

getgid与getegid

头文件

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

gid_t getgid(void); 获取当前进程使用用户组ID

gid_t getegid(void); 获取当前进程有效用户组ID

实例程序

全局变量的共享问题

普通全局变量没有共享, 但是地址空间相同

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

int counter = 200;

int main(int argc, const char* argv[])
{
    int i;
    pid_t pid;
    for(i=0; i<5; ++i) {    // 通过i可区分进程
        pid = fork();
        if(pid == 0)        // 子进程跳出for循环
            break;
    }

    if(i<5) {
        counter += 300;
        printf(" child process , pid = %d,  ppid = %d\n", getpid(), getppid());
        printf("counter = %d, &counter = %p\n\n", counter, &counter);

    }
    else if(i == 5) {
        counter += 100;
        printf(" parent process, pid = %d, ppid = %d, &counter = %p\n", getpid(), getppid(), &counter);
        printf("counter = %d, &counter = %p\n\n", counter, &counter);
        sleep(1);
    }

    return 0;
}

/*
 child process , pid = 25474,  ppid = 25473
counter = 500, &counter = 0x60104c

 parent process, pid = 25473, ppid = 22642, &counter = 0x60104c
counter = 300, &counter = 0x60104c

 child process , pid = 25475,  ppid = 25473
counter = 500, &counter = 0x60104c

 child process , pid = 25476,  ppid = 25473
counter = 500, &counter = 0x60104c

 child process , pid = 25477,  ppid = 25473
counter = 500, &counter = 0x60104c

 child process , pid = 25478,  ppid = 25473
counter = 500, &counter = 0x60104c

*/

孤儿进程

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

int main(void) {
    pid_t pid;

    printf("haha\n");

    pid = fork();
    if (pid < 0) {
        perror("fork error");
        exit(1);
    }
    else if (pid == 0) {
        printf("child, pid: %d, ppid: %d\n", getpid(), getppid());
        sleep(1);
    }
    else {
        printf("parent, pid: %d\n, ppid: %d\n", getpid(), getppid());
    }
    
    printf("haha\n");

    return  0;
}

/*
[zyb@server fork]$ ./a.out 
haha
parent, pid: 25654
, ppid: 22642
haha
[zyb@server fork]$ child, pid: 25655, ppid: 1
haha

[zyb@server fork]$ 
*/

僵尸进程

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

int main(void) {
    pid_t pid;

    printf("haha\n");

    pid = fork();
    if (pid < 0) {
        perror("fork error");
        exit(1);
    }
    else if (pid == 0) {
            printf("child, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
    }
    else {
        while (1) {
            printf("parent, pid: %d\n, ppid: %d\n", getpid(), getppid());
            sleep(5);
        }
    }
    
    printf("haha");

    return  0;
}

/*
[zyb@server ~]$ ps aux | grep "a.out"
zyb       27627  0.0  0.0   4212   344 pts/0    S+   22:50   0:00 ./a.out
zyb       27628  0.0  0.0      0     0 pts/0    Z+   22:50   0:00 [a.out] <defunct>
zyb       27630  0.0  0.0 112704   968 pts/1    S+   22:50   0:00 grep --color=auto a.out
*/