Linux 进程控制

发布于 2023-02-25 12:12:26 字数 5159 浏览 91 评论 0

1 fork 与 vfork 函数

UNIX 提供了两个函数用于创建新进程

#include <unistd.h>
pid_t fork();                   /* 子进程中返回0,父进程中返回子进程ID,出错返回-1 */
pid_t vfork();                  /* 子进程中返回0,父进程中返回子进程ID,出错返回-1 */

1.1 fork 出来的子进程有几点要注意:

  • 子进程与父进程分别持有相同的文件描述符,这些文件描述符共用核心中的同一个文件项
  • 父进程设置的文件锁不会被子进程继承
  • 子进程的未处理的闹钟(alarm)被清除
  • 子进程的未处理信号集设置为空集
  • 当子进程终止时,内核会向父进程发送 SIGCHLD 信号,但对该信号,系统的默认动作是忽略它
  • 子进程会继承父进程的信号处理方式,因为子进程在开始时复制了父进程的存储映像,随意信号捕捉函数的地址在子进程中是有意义的

1.2 fork 与 vfork 的区别在于

  • 在子进程调用 exec 或 exit 之前,vfork 并不会将父进程的地址空间复制到子进程中,即 子进程在父进程的空间中运行,因此子进程运行的结果会影响到父进程
  • vfork 保证子进程先运行,在它调用 exec 或 exit 之后,父进程才可能被调度运行

2 wait 和 waitpid 函数

#include <sys/wait.h>

/* 若成功则返回进程 ID:0,若出错则返回 -1 */
pid_t wait(int* status);
pid_t waitpid(pid_t pid,int* status,int options);
  • 如果所有子进程还在运行,则阻塞
  • 如果一个子进程已终止,则父进程获取其终止状态并返回子进程 pid
  • 如果父进程没有任何子进程,则 报错返回
  • waitpid 可以通过设置选项,使得调用者不阻塞

2.1 参数 status 说明

参数 status 可以为空指针,表示不关心终止状态

<sys/wait.h> 中有定义四个宏来获取进程终止的原因

WIFXITED(status)

子进程是否正常终止,若为真,则可以通过宏 WEXITSTATUS(status) 来获取退出的状态码

WIFSIGNALED(status)

子进程是否因收到一个不可捕获的信号而异常退出,若为真,可以通过 WTERMSIG(status) 获取信号编号,某些系统可以通过 WCOREDUMP(status) 判断是否产生 core 文件

WIFSTOPPED(status)

子进程是否处于 stop 状态,若为真,则可以通过 WSTOPSIG(status) 来获取使子进程暂停的信号编号

WIFCONTINUED(status)

子进程是否处于 continue 状态

2.2 参数 pid 的说明

  • pid == -1,等待任一子进程,此时 waitpid 与 wait 等效
  • pid > 0,等待进程 id 与 pid 相等的子进程
  • pid == 0,等待组 ID 等于调用进程组 ID 的任一子进程
  • pid < -1,等待其组 ID 等于 pid 绝对值的任一子进程

2.3 参数 optioins 说明

通过设置 options 参数,waitpid 不一定等到子进程退出来能获取子进程的状态,也能在子进程处于 stop 或 continue 状态时返回子进程的状态

  • WNOHANG:waitpid 不阻塞
  • WUNTRACED:若子进程处于 stop 状态,且该 stop 状态尚未报告时,返回其状态
  • WCONTINUED:若子进程处于 continue 状态,且该 continue 状态尚未报告时,返回其状态.

3 waitid 函数

waitid 可以指定要监控的子进程的哪些状态变化

#include <sys/wait.h>

int waitid(idtype_t idtype,id_t id,siginfo_t* infop,int options);
  • 参数 idtype_t 指定了要等待的子进程的类型
    P_PID
    等待一个特定的进程
    P_PGID
    等待一个特定进程组中的任一子进程
    P_ALL
    等待任一子进程,此时忽略参数 id 的值
  • 参数 id 的作用则跟 idtype 的值相关
  • 参数 options 指定关注子进程的哪些状态变化
    WNOHANG
    非阻塞等待
    WNOWAIT
    不破坏子进程的退出状态,该状态可由后续 wait,waitid 或 waitpid 调用获取
    WSTOPPED
    等待一个尚未报告的 STOP 状态的子进程
    WCONTINUED
    等待一个尚未报告的 CONTINUE 状态的子进程
    WEXITED
    等待已退出的子进程

4 exec 系列函数

  • 由于 exec 一个新程序后,信号处理函数的地址已经失效了,因此 exec 函数将原先设置为要捕获的信号都更改为它们的默认动作

4.1 exec 系列函数的区分

  • 字母p表示该函数可以为不带目录的文件名,则会从 PATH 环境变量中搜索可执行文件
  • 字母l表示该函数的参数要一个一个的在函数签名中列出来,最后以一个(char*)0 结尾表示参数终结
  • 字母v表示该函数取一个 argv[] 数组作为传递給新进程的参数
  • 字母e表示该函数接收一个 envp[] 数组,可以分配不同于当前环境的新环境

4.2 exec 后的新进程与原进程的关系

  • 新进程保持
    • 原 pid 和 ppid
    • 原实际用户 id 和实际组 id
    • 附加组ID
    • 进程组ID
    • 会话ID
    • 控制终端
    • alarm尚存留的事件
    • 当前工作目录
    • 根目录
    • 文件模式创建屏蔽字
    • 文件锁
    • 进程信号屏蔽
    • 未处理信号
    • 资源限制
    • tms_utime、tms_stime、tms_cutime 及 tms_cstime
  • 是否关闭原进程打开的文件与该文件描述符的 close-on-exec 标志有关
    • 若设置了该标志,则指向 exec 时会关闭该描述符
    • 若没设置该标准,则保持描述符打开
    • 除非特地用 fcntl 设置了该标志,否则系统的默认为关闭该标志
  • exec 时 明确会关闭打开的目录流(opendir)

4.3 当 exec 调用一个带 #! 解析器程序 可选参数项 的脚本文件时:

1、exec 实际执行的并不是该脚本文件,而是脚本文件第一行 #! 解析器程序 可选参数项 中的 解析器程序

2、exec 传递给该解析器程序的参数顺序为,解析器地址,可选参数,脚本文件地址,除 argv0 外的由 exec 函数传入的其他参数

/*
  /tmp/testinterp的内容为:
  #! /usr/bin/echo.exe args:
*/

#include <unistd.h>
int main(){
  execl("/tmp/testinterp","testinterp","myarg1","MY ARG2",(char*) 0);
}
args: /tmp/testinterp myarg1 MY ARG2

5 进程会计

大多数 UNIX 系统都提供了一个选项以进行进程会计(process accounting)处理,启用该选项后,每当进程结束时,内核就写一个会计记录

会计记录是在 fork 时产生而不是 exec 时产生 但 exec 会改变响应记录中的命令名,而且 AFORK 标志也会被清除

会计记录一般为二进制格式的,且结构各个系统实现的都不一样,一般可以在 <sys/acct.h> 中查到 struct acct

root 用户可以使用 accton 命令行来对命令行开启进程会计选项

6 进程时间

任何进程都可以通过调用 times 函数获得自己的运行时间,用户态 CPU 时间和内核态 CPU 时间

#include <sys/times.h>

/* 若成功返回进程相对上一次运行 times 函数的运行时间,单位为时钟滴答数,若出错返回 -1 */
clock_t times(struct tms* buf); 

struct tms{
  clock_t tms_utime;            /* user CPU time */
  clock_t tms_stime;            /* system CPU time */
  clock_t tms_cutime;           /* user CPU tim, terminated children */
  clock_t tms_cstime;           /* system CPU time, terminated children */
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

箜明

暂无简介

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文