Loading

C语言--进程相关函数

获取进程ID

头文件:#include <unistd.h>

  1. pid_t getpid(void):获取进程ID
  2. pid_t getppid(void):获取父进程ID
  3. pid_t getuid(void):获取用户ID
  4. pid_t geteuid(void):获取有效用户ID
  5. pid_t getgid(void):获取组ID
  6. pid_t getegid(void):获取有效组ID

其中pid_t类型本质是无符号整型,定义在头文件#include <types.h>,在不同的平台上上可能是typedef int pid_t或是typedef long pid_t

示例

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

int main() {
    printf("the process id is [%d]\n", getpid());
    printf("the parent process id is [%d]\n", getppid());
    printf("the user id is [%d]\n", getuid());
    printf("the effective id is [%d]\n", geteuid());
    printf("the group id is [%d]\n", getgid());
    printf("the effective group id is [%d]\n", getegid());
    return 0;
}

结果

the process id is [2749]
the parent process id is [721]
the user id is [1000]
the effective id is [1000]
the group id is [1000]
the effective group id is [1000]

设置进程ID

  1. setuid()
    头文件:#include <unistd.h>;
    声明:int setuid(uid_t uid);
    功能:修改用户ID(无论是否有效),参数uid表示改变后的新ID;
    返回值:如果成功修改当前进程的用户ID,返回0;否则返回-1;
  2. seteuid()
    头文件:#include <unistd.h>;
    声明:int seteuid(uid_t uid);
    功能:修改有效用户的ID,参数uid表示改变后的新ID;
    返回值:如果成功修改当前进程的有效用户ID,返回0;否则返回-1;
  3. setgid()
    头文件:#include <unistd.h>;
    声明:int setgid(gid_t gid);
    功能:修改组ID(无论是否有效),参数gid表示改变后的ID;
    返回值:如果修改成功返回0;否则返回-1;
  4. setegid()
    头文件:#include <unistd.h>
    声明:int setegid(gid_t gid);
    功能:修改有效组ID,参数gid表示改变后的ID;
    返回值:如果修改成功返回0,否则返回-1;

创建进程

  1. fork()
    头文件:#include <unistd.h>
    声明:pid_t fork(void);
    功能:创建一个新进程,得到一个新的可用进程ID。并将父进程的数据段和堆栈段复制到子进程的进程空间,并且和父进程共享代码段(代码段是只读的,不存在修改的问题)
    返回值:
  • 父进程中,返回新创建的子进程的进程ID
  • 子进程中,返回值为0
  • 出现错误,返回负值
    fork()出错的原因:
  • 当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN
  • 系统内存不足,这时errno的值被设置为ENOMEM
    注意:创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
    示例:
#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t fpid;
    int count = 0;
    fpid = fork();
    if (fpid < 0) {
        printf("ERROR IN FORK!");
    } else if (fpid == 0) {
        printf("[ %d ] this is child process\n", getpid());
        count++;
    } else {
        printf("[ %d ] this is parent process\n", getpid());
        count++;
    }
    printf("%d\n", count);
    return 0;
}

结果

[ 2812 ] this is parent process
1
[ 2813 ] this is child process
1

当程序执行到fpid = fork()后就是出现两个进程,分别是父进程和子进程,可以说fork()就是将当前进程的情况拷贝了一份,执行相同的代码段,通过变量fpid来控制父子进程实现不同功能,达到想要的效果。

  1. wait()
    头文件:<sys/types.h>、<unistd.h>
    声明:pid_t wait(int* status);
    功能: 使进程进入阻塞状态,直到任意子进程结束或者该进程接受到信号为止;如果该进程没有子进程,或子进程已经结束,wait()会立即返回;参数status为空时表示忽略子进程退出时的状态,不为空表示保存子进程退出时的状态;[1]
    返回值:如果成功,返回被收集的子进程的进程ID;如果没有子进程,调用会失败,返回-1,同时errno被置为ECHILD
  2. waitpid()
    头文件:#include <sys/types.h
    声明:pid_t waitpid(pid_t pid, int* status, int options)
    功能:
    参数:
  • pid
  1. 传入大于0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去
  2. 传入等于-1时,等待任意子进程(作用与wait()相同)
  3. 传入等于0时,等待其组ID等于调用进程的组ID的任意子进程
  4. 传入小于-1时,等待其组ID等于PID的绝对值的任意子进程
  • status: 为空时表示忽略子进程退出时的状态,不为空表示保存子进程退出时的状态
  • options:
  1. 传入等于0时,同wait()阻塞父进程
  2. 传入为WNOHANG,若由PID指定的子进程并不立即可用,则waitpid不会被阻塞,此时返回值为0,子进程结束时返回子进程PID
  3. 传入为WUNTRACED,涉及跟踪调试,使用极少,不多赘述

退出进程

  1. exit()
    头文件:#include <stdlib.h>
    声明:void exit(int status)
    功能:使进程终止,并清除缓冲区;参数status是该程序的退出状态,如果正常退出参数为0;异常退出为非0
    返回值:无返回值
  2. _exit()
    头文件:#include <unistd.h>
    声明:void _exit(int status)
    功能: 使进程终止,不清除缓冲区

  1. 父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。 ↩︎

posted @ 2023-01-03 14:28  henryLyg  阅读(151)  评论(0编辑  收藏  举报