当前位置: 首页 > news >正文

Linux软件编程(五)(exec 函数族、system、线程)

子进程资源回收

当子进程结束后,如果父进程没有回收其资源,会留下 僵尸进程
回收方式主要有 waitwaitpid


1.1 wait

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *wstatus);

功能
阻塞等待 任意子进程 退出,并回收其资源空间。

参数

  • wstatus:保存子进程退出状态的变量地址

  • NULL:不保存退出状态

返回值

  • 成功:回收的子进程 PID

  • 失败:-1


1.2 waitpid

#include <sys/types.h>

#include <sys/wait.h>

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

功能
回收 指定子进程 资源,功能比 wait 更灵活。

参数说明

  • pid

    • < -1:回收指定进程组的任意子进程(如 -100 表示等待 GID=100 的进程组)

    • -1:回收任意子进程

    • 0:回收与调用者同一进程组的所有子进程

    • > 0:回收指定 PID 的子进程

  • status

    • 子进程退出时候的状态,
      如果不关注退出状态用NULL;

  • options

    • 0  表示回收过程会阻塞等待;
      WNOHANG 表示非阻塞模式回收资源。

返回值

  • 成功:成功 返回接收资源的子进程PID

  • 失败:-1

  • 非阻塞模式下且无子进程退出:0


1.3 资源回收策略

  • 阻塞回收waitwaitpid(pid, ..., 0)

  • 非阻塞回收waitpid + WNOHANG(适合轮询)

  • 不回收:子进程的任务需要一直执行

  • 异步回收:配合信号(如 SIGCHLD)实现,子进程退出时通知父进程

一、exec 函数族

在一个进程里面执行另一个文件(可执行文件)。
本质:将进程文本区的指令代码替换成 exec 要执行的文件的指令。
执行成功后不返回,执行失败返回 -1。


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

  • 功能:执行指定路径的可执行文件

  • 参数

    • path可执行文件的路径和名称

    • arg:执行该文件时要传递的参数(arg0 通常为程序本身的名称)

    • NULL:参数结束标志

  • 返回值

    • 出错:-1


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

  • 功能:从 PATH 指定的系统路径中寻找可执行文件

  • 参数

    • file:可执行文件的名称(系统路径下已有)

    • arg:执行该文件时要传递的参数

    • NULL:参数结束标志


3. int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);

  • 功能:执行指定路径的可执行文件,并可传入自定义环境变量

  • 参数

    • path:可执行文件路径

    • arg:参数列表

    • NULL:参数结束标志

    • envp[]:自定义环境变量数组(KEY=value 格式,以 NULL 结束)


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

  • 功能:执行指定路径的可执行文件,参数用字符串数组传递

  • 参数

    • path:可执行文件路径

    • argv[]:参数数组(最后一个元素为 NULL)


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

  • 功能:从 PATH 系统路径搜索文件,参数用字符串数组传递

  • 参数

    • file:文件名(系统路径中已有)

    • argv[]:参数数组(最后一个元素为 NULL)


6. int execvpe(const char *file, char *const argv[], char *const envp[]);

  • 功能:结合 execvp 功能,并支持自定义环境变量(GNU 扩展)

  • 参数

    • file:文件名(从 PATH 搜索)

    • argv[]:参数数组(NULL 结束)

    • envp[]:环境变量数组(NULL 结束)


exec 名称含义

  • l:list(参数列表传递)

  • p:path(从系统 PATH 中查找)

  • v:vector(数组传递)

  • e:environment(可传自定义环境变量)


二、system 函数

作用
system() 会调用一次 fork() 创建子进程,在子进程中执行命令,父进程等待子进程结束。

#include <stdlib.h> int system(const char *command);

特点

  • 简单易用

  • 内部实际是 fork() + exec() + wait()

  • 需要 shell 环境解析命令


三、自定义 system 实现

通过 fork() + execvp() 手动实现 system 功能:

#include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> #include <string.h> int my_system(char *buff) { char *arg[10] = {NULL}; char cmd[512] = {0}; strcpy(cmd, buff); int i = 0; arg[i] = strtok(cmd, " "); while (arg[i] != NULL) { i++; arg[i] = strtok(NULL, " "); } pid_t pid = fork(); if (pid > 0) { wait(NULL); } else if (pid == 0) { execvp(arg[0], arg); } return 0; } int main() { printf("system : pid = %d\n", getpid()); my_system("ls -l"); printf("After system\n"); return 0; }


四、线程

1. 概念

  • 进程:操作系统资源分配的最小单位

  • 线程:操作系统任务调度的最小单位

  • 线程由进程创建,拥有 独立的 8M 栈区,但共享进程的堆区、数据区、文本区

2. 进程与线程对比

对比进程线程
资源消耗分配 0~4G 虚拟空间,开销大只分配 8M 栈区,开销小
创建速度
数据共享需 IPC直接共享进程内存
安全性高,互不影响低,一个线程崩溃可能导致整个进程崩溃

3. 线程相关编程

创建线程

#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

获取线程 ID

pthread_self();

注意:编译需加 -lpthread


五、线程创建示例

#include <stdio.h> #include <pthread.h> #include <unistd.h> void *task(void *arg) { printf("I am thread : tid = %ld\n", pthread_self()); return NULL; } int main() { pthread_t tid; if (pthread_create(&tid, NULL, task, NULL) != 0) { printf("pthread_create error\n"); return -1; } sleep(2); // 防止主线程提前结束 return 0; }

http://www.lryc.cn/news/621770.html

相关文章:

  • Unity导航寻路轨迹可视化实现
  • Unity_数据持久化_Json
  • Ubuntu DNS 综合配置与排查指南
  • 小程序上拉加载下一页数据
  • 基于HTML5与Tailwind CSS的现代运势抽签系统技术解析
  • GEO入门:什么是生成式引擎优化?它与SEO的根本区别在哪里?
  • 流处理、实时分析与RAG驱动的Python ETL框架:构建智能数据管道(中)
  • Fanuc机器人EtherCAT通讯配置详解
  • 【Linux基础知识系列】第九十六篇 - 使用history命令管理命令历史
  • 【机器人】人形机器人“百机大战”:2025年产业革命的烽火与技术前沿
  • Zabbix【部署 01】Zabbix企业级分布式监控系统部署配置使用实例(在线安装及问题处理)程序安装+数据库初始+前端配置+服务启动+Web登录
  • 在 Vue2 中使用 pdf.js + pdf-lib 实现 PDF 预览、手写签名、文字批注与高保真导出
  • 力扣习题:基本计算器
  • Spring 工具类:StopWatch
  • Java 泛型类型擦除
  • 【递归、搜索与回溯算法】DFS解决FloodFill算法
  • Pytest项目_day17(随机测试数据)
  • JUC学习笔记-----LongAdder
  • 2025年最新油管视频下载,附MassTube下载软件地址
  • 嵌入式 C 语言编程规范个人学习笔记,参考华为《C 语言编程规范》
  • 嵌入式硬件篇---电容串并联
  • 嵌入式硬件篇---电容滤波
  • flutter开发(二)检测媒体中的静音
  • Flinksql bug: Heartbeat of TaskManager with id container_XXX timed out.
  • 对抗损失(GAN)【生成器+判断器】
  • LeetCode 922.按奇偶排序数组2
  • 大模型LLM部署与入门应用指南:核心原理、实战案例及私有化部署
  • 解决安装特定版本 anaconda-client 的错误
  • CSS从入门到精通完整指南
  • 【科研绘图系列】R语言绘制三维曲线图