进程和线程(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;失败返回错误码。

相关推荐
小王C语言1 小时前
云服务器重置后,vscode无法远程连接
运维·服务器
Zzzzmo_1 小时前
【网络原理】TCP/IP协议02
网络·tcp/ip
RoboWizard1 小时前
金士顿高性能存储 赋能工控行业多场景深度落地
运维·服务器
DianSan_ERP1 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
数据知道2 小时前
漏洞挖掘方法论:从 Fuzz 到 0day 的思维框架
网络·安全·web安全·网络安全
会飞的土拨鼠呀2 小时前
Linux 真实内存使用率的核心计算标准
linux·运维·服务器
智购科技自动售货机工厂2 小时前
2026自动售货机语音支付模块集成:从声纹识别到支付闭环的工程实践~YH
大数据·服务器·网络·数据库·人工智能
陈年老古董3 小时前
CentOS编译安装Python3.11完整教程
linux·笔记·学习·centos·python3.11
深念Y3 小时前
为什么选 Go:直观、可维护、AI 友好
linux·开发语言·人工智能·golang·agent·harness