1、回收资源空间:wait() 与 waitpid()
僵尸进程(Zombie Process):
定义:进程退出后,其资源空间尚未被父进程回收的状态。
特点:
-
进程已终止,但仍在进程表中保留条目
-
占用少量系统资源(如 PID),但不消耗 CPU 和内存
-
无法被杀死,必须由父进程回收
如何避免僵尸进程产生?
-
父进程及时调用 wait() 或 waitpid() 回收子进程资源
-
让子进程成为孤儿进程(Orphan Process),由系统自动回收
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);
阻塞等待并回收任意一个已终止的子进程资源。
该函数会暂停父进程,直到某个子进程结束。
参数:
wstatus:指向整型变量的指针,用于保存子进程退出状态
若不关心退出状态,可设为 NULL
返回值:
成功:返回被回收的子进程的 PID
失败:返回 -1(通常表示没有子进程或系统错误)
wait(NULL); // 不关心退出状态,仅回收子进程资源
2、 pid_t waitpid(pid_t pid, int *status, int options); (了解)
回收指定进程的资源。 与 wait 功能相似,但比 wait 更灵活,可以指定等待哪个子进程。
参数说明:pid:指定要等待的子进程 ID
< -1:回收指定进程组内的任意子进程(例如:-100 表示等待 GID=100 的进程组中的任意子进程)
= -1:回收任意子进程(不限于当前进程组)
= 0:回收与当前调用 waitpid 的进程同属一个组的所有子进程
> 0:回收指定 PID 的子进程
status:指向整型变量的指针,用于保存子进程退出状态
如果不关心退出状态,可设为 NULL
options:选项标志
0:表示阻塞等待(默认)
WNOHANG:非阻塞模式,若没有子进程退出则立即返回
返回值:
成功:返回被回收的子进程的 PID
失败:返回 -1
若设置 WNOHANG 且无子进程可回收:返回 0
子进程资源空间回收策略:
(1) wait 阻塞回收:父进程调用 wait() 阻塞等待子进程结束
(2)waitpid 非阻塞方式回收:使用 waitpid() 并设置 options 为 WNOHANG 实现非阻塞,父进程可在循环中轮询检查是否有子进程退出
(3)不回收:子进程任务需一直执行
(4)异步回收:使用信号机制(如 SIGCHLD)通知父进程子进程已结束
3、exec:函数族
在一个进程里面执行另外一个文件(可执行文件):
本质:将文本去的指令代码替换为 exec 要执行的文件的指令。
int execl(const char *path, const char *arg, ... /* (char *) NULL */);
参数:
path:要执行的可执行文件的路径和名称
arg:执行该可执行文件时需要传递的参数
NULL:参数传递结束标志
返回值:
出错:-1
int execlp(const char *file, const char *arg, ... /* (char *) NULL */);
功能:从 PATH 指定的系统路径下寻找该可执行文件
参数:
file:需要执行的可执行文件的名称(系统路径下已有的文件)
arg:执行该可执行文件时需要传递的参数
int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
4、线程:
(1) 什么是线程
轻量级的进程,可实现多任务的并发。
进程是操作系统资源分配的最小单位;
线程是操作系统任务调度的最小单位。
(2)线程的创建
线程由某个进程创建。
进程创建线程时,会为其分配独立的(8M)栈区空间;
线程和所在进程,以及进程中的其他线程,共用进程的堆区、数据区、文本区。

(3)线程的调度:宏观并行,微观串行
(4)线程消亡
-
线程退出
-
回收线程资源空间
(5)进程和线程的区别:
进程:
-
进程是操作系统资源分配的最小单位;
-
资源消耗:进程资源开销大,每次创建都需要有 0-4G 的虚拟内存空间;
-
效率角度:由操作系统创建,创建时耗时比线程大;跨进程调度比跨线程调度慢;
-
通信方面:进程间不能直接通信,需要使用进程间通信机制(IPC 机制);
-
安全性角度:进程安全性比线程高,各进程空间独立。
线程:
-
线程是操作系统任务调度的最小单位;
-
资源消耗:资源开销较小,只需要所在进程为其开辟 8M 的栈区空间;
-
效率角度:由所在进程创建;跨进程调度比跨线程调度慢;
-
通信方面:通信简单,可以使用线程共享的区域进行通信(比如全局变量);
-
安全性角度:线程没有进程安全性好,一个线程异常可能影响同一进程中的所有线程。
(6) 线程的相关编程
线程的创建:pthread_create()
pthread_self():获取当前线程的ID号
线程调度:由操作系统调度
线程消亡:
-
线程退出:pthread_exit();
-
线程回收:pthread_join();
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
参数:
thread:保存线程ID的变量地址
attr:线程属性的对象地址
NULL:按照默认属性创建
start_routine:函数的指针:指向线程启动后要执行的任务(线程任务函数)
arg:为线程任务函数传递的参数
返回值:
成功:0
失败:非0