进程和线程(2)

Linux多进程与多线程学习总结(CSDN风格)

一、进程回收 waitpid

函数原型

复制代码
pid_t waitpid(pid_t pid, int *wstatus, int options);

功能:回收指定子进程资源,避免僵尸进程。

参数说明

  1. pid:要回收子进程PID
  2. wstatus:传出参数,保存子进程退出状态的地址
  3. options
    • 0:阻塞回收,子进程没结束就卡住等待
    • 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 *)NULL
  • v: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;,存放整个进程全部环境变量。

四、进程与线程核心区别

  1. 进程:操作系统资源分配最小单元
    • 每个进程拥有独立完整虚拟地址空间(0‑4G):文本段、数据段、堆、栈全部私有。
    • 进程之间完全隔离,通信必须IPC(管道、共享内存、消息队列)。
  2. 线程:操作系统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:要回收的线程ID
  • retval:二级指针,接收pthread_exit传出的返回值;不需要接收填NULL。

返回:成功返回0;失败返回错误码。

相关推荐
0+1115 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
青瓦梦滋5 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
桌面运维家6 小时前
旧电脑跑不动课程软件,VDI云桌面怎样接着用?
运维·服务器·虚拟化·pve·vdi·云桌面
zhang133830890756 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻6 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
IpdataCloud8 小时前
批量查IP的API接口怎么选?免费API配额瓶颈与离线库本地批量方案实测
网络·网络协议·tcp/ip
2601_949847758 小时前
bcrypt.js 跨端三方库仓颉适配全流程
linux·运维·ubuntu
m0_639906948 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
今天重构了吗9 小时前
Linux 上 rm -rf 删错了能找回吗
运维·服务器
ITyunwei09879 小时前
售后夜间值守怎么落地:从告警到交接的工单系统配置笔记
网络