Linux多进程与多线程学习总结(CSDN风格)
一、进程回收 waitpid
函数原型
pid_t waitpid(pid_t pid, int *wstatus, int options);
功能:回收指定子进程资源,避免僵尸进程。
参数说明
pid:要回收子进程PIDwstatus:传出参数,保存子进程退出状态的地址options0:阻塞回收,子进程没结束就卡住等待WNOHANG:非阻塞回收,子进程未结束直接返回0,不阻塞
返回值
- 成功:返回被回收子进程PID
- 子进程未结束(WNOHANG):返回0
- 出错:返回
‑1
对比:
wait()只能任意阻塞回收子进程;waitpid()可以精准指定PID,支持非阻塞轮询。
二、exec函数族
exec系列:覆盖当前进程地址空间,去执行新程序,PID保持不变。调用成功原有代码不再执行;只有失败才返回‑1。
| 函数 | 后缀含义 | 调用形式特点 |
|---|---|---|
execl |
l(list) | 路径+可变参数列表,(char *)NULL结尾 |
execlp |
l+p | PATH环境变量搜索程序名,列表传参 |
execle |
l+p+e | 路径+列表+自定义环境变量表 |
execv |
v(vector) | 路径+字符串指针数组argv |
execvp |
v+p | 文件名,从PATH查找,数组传参 |
execvpe |
v+p+e | 文件名+数组+自定义环境变量 |
记忆口诀:
l:list,可变列表传参 ,参数逐个写,末尾必须(char *)NULLv:vector,指针数组传参,把参数放到char*数组p:path,会读取系统PATH环境变量,只写程序名不用写完整路径e:env,可传入自定义环境变量,不使用默认全局environ
返回值:成功无返回;失败返回‑1。
注意:exec执行成功,后面代码直接丢弃,不会运行。一般搭配fork,子进程中调用exec。
三、环境变量 setenv
int setenv(const char *name, const char *value, int overwrite);
功能:设置/修改进程环境变量。
参数:
name:环境变量名value:环境变量值overwrite:非0覆盖原有值;0若变量已存在,不做修改。
返回:成功返回0;失败返回‑1。
全局环境变量:extern char **environ;,存放整个进程全部环境变量。
四、进程与线程核心区别
- 进程:操作系统资源分配最小单元
- 每个进程拥有独立完整虚拟地址空间(0‑4G):文本段、数据段、堆、栈全部私有。
- 进程之间完全隔离,通信必须IPC(管道、共享内存、消息队列)。
- 线程:操作系统CPU调度最小单元(轻量级进程)
- 线程存在于进程内部;同一个进程内所有线程共享:文本段、全局变量、静态变量、堆、环境变量。
- 每个线程独有:自己的栈空间(默认8MB),局部变量存在线程栈,线程私有。
宏观并行,微观串行:多个线程/进程交替使用CPU,看上去同时运行。
| 进程操作 | 对应线程接口 |
|---|---|
| fork() 创建子进程 | pthread_create() 创建线程 |
| exit() 退出进程 | pthread_exit() 退出线程 |
| wait/waitpid() 回收子进程 | pthread_join() 回收线程 |
⚠️线程不调用pthread_join回收,会产生僵尸线程,内存资源泄漏。
五、线程API详解
1. pthread_create 创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
thread:传出参数,保存线程ID(TID)attr:线程属性,栈大小、分离属性,填NULL使用默认start_routine:线程入口函数,格式固定void* fun(void* arg)arg:传给线程函数唯一参数,void*万能指针
返回:成功返回0;失败返回错误编号。
重点坑:给线程传参,不要直接传局部变量地址;多线程并发会竞争,优先malloc堆内存传递,线程内部free释放。
禁止直接
(void *)i把int数字强制转指针,64位下报大小不匹配警告。
2. pthread_exit 线程退出
void pthread_exit(void *retval);
功能:结束当前线程,不影响同进程其他线程。
retval:线程退出返回值,可被pthread_join接收。
注意:不要在线程调用
exit(),exit直接把整个进程全部结束。
3. pthread_join 阻塞回收线程
int pthread_join(pthread_t thread, void **retval);
- 特性:阻塞函数,等待指定线程执行完毕,才返回。
thread:要回收的线程IDretval:二级指针,接收pthread_exit传出的返回值;不需要接收填NULL。
返回:成功返回0;失败返回错误码。