Linux学习笔记:进程回收、exec函数簇与线程

一、进程回收:wait()与waitpid()

子进程退出后,如果父进程不回收它的资源,就会变成僵尸进程。我在学习中主要用两个函数来处理这个问题。

wait()

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *wstatus);

这个函数会阻塞等待,直到有子进程退出才返回。参数wstatus用来保存子进程退出时的状态,不关心的话直接传NULL就行。成功返回回收到的子进程PID,失败返回-1。

waitpid()

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

比wait更灵活,可以指定回收哪个进程。pid参数有几种情况:

<-1 :回收指定进程组内的任意子进程

-1 :回收任意子进程

0 :回收和当前调用进程同组的所有子进程

>0 :回收指定ID的子进程

options传0就是阻塞回收,传 WNOHANG 就是非阻塞。非阻塞模式下如果没回收到子进程会返回0,适合父进程还有其他任务要做的场景,搭配轮询使用。

二、exec函数簇

有时候我需要在一个进程里执行另一个可执行程序,这时候就用到exec函数簇。它的本质是把外部程序替换到当前进程的文本区,进程本身还是那个进程,只是跑的代码变了。

常用的几个:

int execl(const char *path, const char *arg, ... /* (char *) NULL */);

path是可执行程序的完整路径,比如 "/bin/ls" ,后面跟着执行参数,最后必须以NULL结尾。

int execlp(const char *file, const char *arg, ... /* (char *) NULL */);

和execl类似,但它会去PATH环境变量保存的路径里找可执行文件,所以file直接写程序名就行,比如 "ls" 。

int execv(const char *path, char *const argv\[\]);

int execvp(const char *file, char *const argv\[\]);

这两个是把参数放在一个指针数组里传进去,而不是一个个列出来。

命名规律其实挺好记:l代表list(参数列表形式),p代表PATH(走环境变量查找),v代表vector(数组形式传参)。这些函数只有失败时才有返回值,返回-1,成功的话直接就去执行新程序了,不会再回来。

三、线程

  1. 什么是线程

线程可以理解成轻量级的进程,也是用来实现多任务并发的。有个关键点我记的比较清楚:进程是操作系统资源分配的最小单位,线程是CPU任务调度的最小单位。

线程由所在进程创建,一定属于某个进程。创建线程时,进程只为它分配独立的栈区空间(默认8M),堆区、数据区、文本区、内核区域都是和进程共享的。

  1. 进程和线程的区别

我整理了一张对比表,面试经常问到:

进程 线程

概念 (进程)资源分配的最小单位 (线程)CPU调度的最小单位

效率 (进程)要分配0-4G虚拟内存,开销大 (线程)创建快,只分配栈区,切换也快

内存 (进程)消耗大,并发量相对少 (线程)只独立栈区,其他共享

安全性 (进程)空间独立,安全性高 (线程)共享空间,安全性低一些

通信 (进程)不能直接通信,需要IPC机制 (线程)可以直接通信,全局变量就行

  1. 线程的创建与消亡

线程调度也是宏观并行、微观串行,和进程一样。消亡分两步:线程退出,然后回收线程资源空间。

创建线程用 pthread_create :

#include <pthread.h>

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)。

有两个注意点:

  1. 编译链接时要加线程库参数: -lpthread 或 -pthread

  2. 创建线程的主进程不能先于线程结束,不然线程就没了

相关推荐
一去不复返的通信er4 小时前
力扣-图论-岛屿数量
算法·leetcode·图论
0+1115 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
行思理5 小时前
go语言学习难度及适合学习的人群
开发语言·学习·golang
青瓦梦滋5 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
程序 代码狂人7 小时前
切片表与分区表的区别(数据开发面试版)
java·大数据·开发语言·数据仓库·算法
HDU-Dade8 小时前
【校招笔试真题】简要介绍 Self-Attention 的前沿算法
人工智能·算法
2601_949847758 小时前
bcrypt.js 跨端三方库仓颉适配全流程
linux·运维·ubuntu
m0_639906948 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
楚山之石9 小时前
【Medical Image Analysis】深度学习医学图像合成综述:伪CT、合成MRI与合成PET的架构、性能与临床边界
图像处理·人工智能·学习·mr·mri
Li_RuiQi10 小时前
DAgger方法演进_独立学习笔记
笔记·学习·计算机视觉