【归纳整理】Liunx下的进程管理(三),多进程的等待和终止

进程的正常退出

------------------

1. 从main函数中return。

int main (...) {

...

return x;

}

等价于:

int main (...) {

...

exit (x);

}

2. 调用标准C语言的exit函数。

#include <stdlib.h>

void exit (int status);

1) 调用进程退出,

其父进程调用wait/waitpid函数返回status的低8位。

2) 进程退出之前,

先调用所有事先通过atexit/on_exit函数注册的函数,

冲刷并关闭所有仍处于打开状态的标准I/O流,

删除所有通过tmpfile函数创建的文件。

#include <stdlib.h>

int atexit (void (*function) (void));

function - 函数指针,

指向进程退出前需要被调用的函数。

该函数既没有返回值也没有参数。

成功返回0,失败返回非零。

int on_exit (void (*function) (int, void*), void* arg);

function - 函数指针,

指向进程退出前需要被调用的函数。

该函数没有返回值但有两个参数:

第一参数来自exit函数的status参数,

第二个参数来自on_exit函数的arg参数。

arg      - 任意指针,

将作为第二个参数被传递给function所指向的函数。

成功返回0,失败返回非零。

3) 用EXIT_SUCCESS/EXIT_FAILURE常量宏

(可能是0/1)作参数,调用exit()函数表示成功/失败,

提高平台兼容性。

4) 该函数不会返回。

5) 该函数的实现调用了_exit/_Exit函数。

3. 调用_exit/_Exit函数。

#include <unistd.h>

void _exit (int status);

1) 调用进程退出,

其父进程调用wait/waitpid函数返回status的低8位。

2) 进程退出之前,

先关闭所有仍处于打开状态的文件描述符,

将其所有子进程托付给init进程(PID为1的进程)收养,

向父进程递送SIGCHILD信号。

3) 该函数不会返回。

4) 该函数有一个完全等价的标准C版本:

#include <stdlib.h>

void _Exit (int status);

4. 进程的最后一个线程执行了返回语句。

5. 进程的最后一个线程调用pthread_exit函数。

进程的异常终止

------------------

1. 调用abort函数,产生SIGABRT信号。

2. 进程接收到某些信号。

3. 最后一个线程对“取消”请求做出响应。

wait/waitpid

----------------

等待子进程终止并获取其终止状态。

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait (int* status);

pid_t waitpid (pid_t pid, int* status, int options);

成功返回终止子进程的PID,失败返回-1。

1. 当一个进程正常或异常终止时,

内核向其父进程发送SIGCHLD信号。

父进程可以忽略该信号,

或者提供一个针对该信号的信号处理函数,默认为忽略。

2. 父进程调用wait函数:

1) 若所有子进程都在运行,则阻塞。

2) 若有一个子进程已终止,

则返回该子进程的PID和终止状态(通过status参数)。

3) 若没有需要等待子进程,则返回失败,errno为ECHILD。

3. 在任何一个子进程终止前,wait函数只能阻塞调用进程,

而waitpid函数可以有更多选择。

4. 如果有一个子进程在wait函数被调用之前,

已经终止并处于僵尸状态,wait函数会立即返回,

并取得该子进程的终止状态。

5. 子进程的终止状态通过输出参数status返回给调用者,

若不关心终止状态,可将此参数置空。

6. 子进程的终止状态可借助

sys/wait.h中定义的参数宏查看:

WIFEXITED(): 子进程是否正常终止,

是则通过WEXITSTATUS()宏,

获取子进程调用exit/_exit/_Exit函数,

所传递参数的低8位。

因此传给exit/_exit/_Exit函数的参数最好不要超过255。

WIFSIGNALED(): 子进程是否异常终止,

是则通过WTERMSIG()宏获取终止子进程的信号。

WIFSTOPPED(): 子进程是否处于暂停,

是则通过WSTOPSIG()宏获取暂停子进程的信号。

WIFCONTINUED(): 子进程是否在暂停之后继续运行

7. 如果同时存在多个子进程,又需要等待特定的子进程,

可使用waitpid函数,其pid参数:

-1 - 等待任一子进程,与wait函数等价;

>0 - 等待特定子进程(由pid参数标识);

0 - 等待与调用进程同进程组的任一子进程;

<-1 - 等待特定进程组(由pid参数的绝对值标识)的任一子进程。

8. waitpid函数的options参数可取0(忽略)或以下值的位或:

WNOHANG    - 非阻塞模式,

若没有可用的子进程状态,则返回0。

WUNTRACED  - 若支持作业控制,且子进程处于暂停态,

则返回其状态。

WCONTINUED - 若支持作业控制,且子进程暂停后继续,

则返回其状态。

八、exec

--------

1. exec函数会用新进程完全替代调用进程,

并开始从main函数执行。

2. exec函数并非创建子进程,新进程取调用进程的PID。

3. exec函数所创建的新进程,

完全取代调用进程的代码段、数据段和堆栈段。

4. exec函数若执行成功,则不会返回,否则返回-1。

5. exec函数包括六种形式:

#include <unistd.h>

int execl  (

const char* path,

const char* arg,

...

);

int execv  (

const char* path,

char* const argv[]

);

int execle (

const char* path,

const char* arg,

...,

char* const envp[]

);

int execve (

const char* path,

char* const argv[],

char* const envp[]

);

int execlp (

const char* file,

const char* arg,

...

);

int execvp (

const char* file,

char* const argv[]

);

l: 新程序的命令参数以单独字符串指针的形式传入

(const char* arg, ...),参数表以空指针结束。

v: 新程序的命令参数以字符串指针数组的形式传入

(char* const argv[]),数组以空指针结束。

e: 新程序的环境变量以字符串指针数组的形式传入

(char* const envp[]),数组以空指针结束,

无e则从调用进程的environ变量中复制。

p: 若第一个参数中不包含“/”,则将其视为文件名,

根据PATH环境变量搜索该文件。

system

----------

#include <stdlib.h>

int system (const char* command);

1. 标准C函数。执行command,

成功返回command对应进程的终止状态,失败返回-1。

2. 若command取NULL,返回非零表示shell可用,

返回0表示shell不可用。

3. 该函数的实现,

调用了vfork、exec和waitpid等函数,

其返回值:

1) 如果调用vfork或waitpid函数出错,则返回-1。

2) 如果调用exec函数出错,则在子进程中执行exit(127)。

3) 如果都成功,则返回command对应进程的终止状态

(由waitpid的status输出参数获得)。

4. 使用system函数而不用vfork+exec的好处是,

system函数针对各种错误和信号都做了必要的处理。

时间: 2024-10-04 23:46:29

【归纳整理】Liunx下的进程管理(三),多进程的等待和终止的相关文章

linux下的进程管理(进程的基本了解及查看pstree,ps,pgrep命令)

Linux下的进程管理 1.什么是进程?程序是静态的文件进程是运行中的程序的一个副本进程存在生命周期(准备期,运行期,终止期)2.进程状态 状态 定义 R(TASK_RUNNING) . 可执行状态(RUNNING,READY)running:正在被处理 ready: 在排队, cpu处理进程个数有限 S(TASK_INTERRUPTIBLE) 可唤醒状态 :在cpu上使用的时间超时,此时被打入休眠状态,随着程序的调用会被唤醒 D(TASK_UNINTERRUPTIBLE) 不可唤醒状态 T(T

【归纳总结】Unix/linux下的进程管理(二):创建进程的函数及其应用、对比

创建进程的函数fork().vfork()和execl() 本次内容主要介绍Unix/linux下2个创建进程的函数fork和vfork以及它们的差别. 1.fork函数 (1)函数的格式 #include <unistd.h> pid_t fork(void); 函数功能: 主要用于以复制正在运行进程的方式来创建新的进程,其中新进程叫做子进程,正在运行的进程叫做父进程. 返回值: 函数调用成功时,父进程返回子进程的PID,子进程返回0,函数调用出错时,父进程返回-1,子进程没有被创建. 注意

Unix下的进程管理

进程的概述 进程的概念 直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统.操作系统会以进程为单位,分配系统资源,所以我们也说,进程是资源分配的最小单位. 进程调度中的三种状态 运行:当一个进程在处理机上运行时,则称该进程处于运行状态.处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个.在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程. 就绪

归纳整理Linux下C语言常用的库函数----内存及字符串控制及操作

在没有IDE的时候,记住一些常用的库函数的函数名.参数.基本用法及注意事项是很有必要的. 参照Linux_C_HS.chm的目录,我大致将常用的函数分为一下几类: 1. 内存及字符串控制及操作 2. 字符串转换 3. 字符测试 4. 文件操作 5. 时间日期 6. 常用数学函数 7. 文件内容操作 8. 文件权限控制 9. 进程操作 10. 线程操作 11. Socket操作 12. 信号处理 13. 数据结构及算法 以下是对第一项 内存及字符串控制及操作 的归纳整理. 已经不赞成使用的函数归类

Linux下的进程管理

在操作系统系统中,进程是一个非常重要的概念. 一.Linux中进程的相关知识 1.什么是进程呢? 通俗的来说进程是运行起来的程序.唯一标示进程的是进程描述符(PID),在linux内核中是通过task_struck和task_list来定义和管理进程的. 2.进程的分类 1)根据在linux不同模式下运行分为: 核心态:这类进程运行在内核模式下,执行一些内核指令(Ring 0). 用户态:这类进程工作在用户模式下,执行用户指令(Ring 3). 如果用户态的进程要执行一些核心态的指令,此时就会产

归纳整理Linux下C语言常用的库函数----文件操作

在没有IDE的时候,记住一些常用的库函数的函数名.参数.基本用法及注意事项是很有必要的. 参照Linux_C_HS.chm的目录,我大致将常用的函数分为一下几类: 1. 内存及字符串控制及操作 2. 字符串转换 3. 字符测试 4. 文件操作 5. 时间日期 6. 常用数学函数 7. 文件内容操作 8. 文件权限控制 9. 进程操作 10. 线程操作 11. Socket操作 12. 信号处理 13. 数据结构及算法 这次主要总结的是上面黑色部分,关于文件操作的函数. 系统调用归类 * * 函数

归纳整理Linux下C语言常用的库函数----时间日期数学及算法

在没有IDE的时候,记住一些常用的库函数的函数名.参数.基本用法及注意事项是很有必要的. 参照Linux_C_HS.chm的目录,我大致将常用的函数分为一下几类: 1. 内存及字符串控制及操作 2. 字符串转换 3. 字符测试 4. 文件操作 5. 时间日期 6. 常用数学函数 7. 文件内容操作 8. 文件权限控制 9. 进程操作 10. 线程操作 11. Socket操作 12. 信号处理 13. 数据结构及算法 时间函数归类 /*时间函数归类 * * 函数名 用法 备注 * *1.char

基于LINUX下的进程管理问题

什么是进程? 程序(program)放置在存储媒体中(如硬盘,光盘,软盘,磁带等)为实体文件的形态存在 进程:程序被触发后,执行者的权限与属性,程序的程序码与所需数据等都会被载入内存中,操作系统并给予这个内存内的单元一个识别码(PID),可以说,进程就是一个正在运行的程序 进程的状态: R(Running):该程序正在运行中: S(Sleep):该程序目前正在睡眠状态(idle),但可以被唤醒(signal) D:不可被唤醒的睡眠状态,通常进程可能在等待I/O的情况. T:停止状态(stop),

【笔记整理】unix/linux的进程管理(一)

Unix/Linux 下的进程管理 1. 进程与程序 ~~~~~~~~~~~~~ 1) 进程就是运行中的程序.一个运行着的程序, 可能有多个进程.进程在操作系统中执行特定的任务. 2) 程序是存储在磁盘上, 包含可执行机器指令和数据的静态实体. 进程或者任务是处于活动状态的计算机程序. 2. 进程的分类 ~~~~~~~~~~~~~ 1) 进程一般分为交互进程.批处理进程和守护进程三类. 2) 守护进程总是活跃的,一般是后台运行. 守护进程一般是由系统在开机时通过脚本自动激活启动, 或者由超级用户