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

从函数调用到进程通信:Linux下的多语言协作实践

目录

程序间调用的优势之一

1、Shell脚本

脚本功能说明:

执行效果

使用方法:

2、Python 脚本 (python.py)

功能说明:

使用方法:

输出:

3、C++ 程序 (test.cc)

功能说明:

编译与运行:

输出:

4、三者的对比总结

补充说明

程序替换

C 程序 (proc.c)

功能说明

编译与运行

对比表格

总结


        当你掌握了C语言、C++或Java等高级语言时,你可能仅了解函数间的相互调用。但随着深入学习进程相关知识,你会发现程序之间同样可以实现相互调用。在学习新内容之前,我们先探讨函数与进程的相似性。exec/exit 机制类似于函数调用中的 call/return 模式。

以C语言为例,你应该掌握以下核心概念:

  1. 一个C程序由多个函数构成,函数之间可以相互调用并传递参数
  2. 被调函数执行特定操作后会返回结果值
  3. 每个函数都拥有独立的局部变量空间
  4. 函数间通过call/return机制进行通信

        这种基于参数传递和返回值、在保持数据私密性的函数间进行通信的模式,构成了结构化程序设计的基础。Linux系统将这种程序内部的设计理念进一步扩展到了程序间的交互中,如下图所示:

        通过fork系统调用,父进程可以创建子进程。随后使用exec系列函数,子进程能够加载并执行其他程序,替换原有代码和数据,子进程通过exit(n)返回状态值,父进程则通过wait(&ret)系统调用获取子进程的退出状态。这种机制实现了程序间的调用与切换。

pid_t id = fork();
if (id == 0){execvp(myargv[0], myargv);exit(1);
}

        程序执行完毕后,会通过exit(n)返回一个状态值。调用进程可使用waitwaitpid函数来获取该返回值。

wait(&status);
waitpid(id, &status, 0);

程序间调用的优势之一

        不同编程语言各有其特长,在实际开发中,我们常需要组合使用多种语言。通过程序间的相互调用,就能实现不同语言的无缝衔接。

例如,C程序可以通过exec系列函数来调用Shell脚本、Python或C++等语言编写的程序。

1、Shell脚本

这是一个简单的 Bash 脚本文件 test.sh,内容如下:

#!/bin/bashi=0
while [ $i -le 10 ]
doecho "hello shell:$i"let i++
done

脚本功能说明:

  1. #!/bin/bash:指定脚本使用 Bash 解释器执行。

  2. i=0:初始化变量 i 的值为 0。

  3. while [ $i -le 10 ]:当 i 的值小于或等于 10 时,循环继续执行。

  4. echo "hello shell:$i":打印字符串 hello shell: 并附带当前 i 的值。

  5. let i++:每次循环结束后,将 i 的值加 1。

  6. done:标记循环结束。

执行效果

        运行此脚本会输出 11 行内容(从 i=0 到 i=10),每行格式为 hello shell: 后跟当前循环计数器的值。

使用方法:

  1. 将脚本保存为 test.sh

  2. 赋予执行权限:chmod +x test.sh

  3. 运行脚本:./test.sh

输出示例:

2、Python 脚本 (python.py)

#!/usr/bin/pythonprint("hello python!")
功能说明
  • #!/usr/bin/python:指定脚本使用 Python 解释器执行。

  • print("hello python!"):打印字符串 hello python!

使用方法
  1. 将脚本保存为 python.py

  2. 赋予执行权限(可选):chmod +x python.py

  3. 运行脚本:

    • 直接执行:./test.py(需确保 Python 路径正确)。

    • 或通过 Python 解释器运行:python python.py

输出

3、C++ 程序 (test.cc)

#include <iostream>
using namespace std;int main()
{cout << "hello C++" << endl;return 0;
}
功能说明
  • #include <iostream>:引入标准输入输出库。

  • using namespace std:使用标准命名空间,避免重复写 std::

  • cout << "hello C++" << endl:打印字符串 hello C++ 并换行。

  • return 0:表示程序正常退出。

编译与运行
  1. 将代码保存为 test.cc

  2. 编译(需安装 g++):

    g++ test.cc -o test
  3. 运行生成的可执行文件:

    ./test
输出

4、三者的对比总结

特性Bash 脚本Python 脚本C++ 程序
文件扩展名.sh.py.cc 或 .cpp
执行方式解释执行(直接或通过 Bash)解释执行(直接或通过 Python)需编译后运行二进制文件
语法复杂度简单(面向命令)简洁(高级抽象)复杂(需管理内存、类型等)
性能低(依赖系统 Shell)中等(解释器开销)高(直接编译为机器码)
典型用途系统管理、自动化任务快速开发、脚本工具高性能应用、底层开发
依赖需 Bash 环境需 Python 环境需编译器(如 g++)

补充说明

  • Bash 脚本 (test.sh):适用于 Linux/Unix 系统自动化任务,无需编译,直接解释执行。

  • Python 脚本 (test.py):跨平台,适合快速开发,解释执行,依赖 Python 环境。

  • C++ 程序 (test.cc):高性能场景,需编译(如 g++ test.cc -o test),生成可执行文件后运行。

程序替换

我们使用以下C程序,便可以分别调用以上三个程序:

C 程序 (proc.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main() {pid_t id = fork();if (id == 0) {// 子进程execl("./test.sh", "test.sh", NULL);  // 调用 Bash 脚本// execl("./python.py", "python.py", NULL); // 调用 Python 脚本// execl("./test", "test", NULL);       // 调用 C++ 程序exit(1);  // 若 execl 失败则退出}// 父进程等待子进程结束int status = 0;pid_t ret = waitpid(id, &status, 0);if (ret > 0) {printf("exit code: %d\n", WEXITSTATUS(status));}return 0;
}

功能说明

  1. 多进程控制

    • 使用 fork() 创建子进程,子进程通过 execl() 调用外部程序。

    • 父进程通过 waitpid() 等待子进程结束,并获取其退出状态码。

  2. 调用方式

    • Bash 脚本execl("./test.sh", "test.sh", NULL)

    • Python 脚本execl("./python.py", "python.py", NULL)(需取消注释)

    • C++ 程序execl("./test", "test", NULL)(需先编译 test.cc 生成 test

  3. 注意事项

    • 被调用的程序(如 test.shpython.pytest)需具有可执行权限。

    • 若 execl() 调用失败,子进程会执行 exit(1),父进程捕获的退出码为 1

编译与运行

  1. 编译 C 程序

    gcc proc.c -o proc
  2. 运行程序

    ./proc
  3. 输出示例: 

调用shell脚本运行结果: 

调用python运行结果: 

调用C++运行结果: 

对比表格

调用目标语言需提前准备C 中调用方法
test.shBash赋予执行权限 (chmod +x)execl("./test.sh", "test.sh", NULL)
test.pyPython确保 Python 环境可用execl("./python.py", "python.py", NULL)
testC++编译生成可执行文件 (g++)execl("./test", "test", NULL)

总结

  • 用途:该 C 程序通过进程管理实现了对多种语言脚本/程序的灵活调用,适用于需要混合编程的场景(如用 C 控制任务流程,调用其他语言模块)。

  • 扩展性:可通过修改 execl() 参数调用其他外部程序(如 Perl、Java 等)。

http://www.dtcms.com/a/281838.html

相关文章:

  • STM32 | 定时器 PWM 呼吸灯
  • 坚持继续布局32位MCU,进一步完善产品阵容,96Mhz主频CW32L012新品发布!
  • 尚庭公寓-------图片上传接口
  • 推客系统开发:从零构建高并发社交平台的技术实践
  • Python爬虫实战:研究PyYAML库相关技术
  • 多维动态规划题解——不同路径【LeetCode】递推写法空间优化
  • 【Qt开发】Qt的背景介绍(二)-> 搭建Qt开发环境
  • 从混沌到秩序:数据科学的热力学第二定律破局——线性回归的熵减模型 × 最小二乘的能量最小化 × 梯度下降的负反馈控制系统,用物理定律重构智能算法的统一场论
  • Blender 云渲染高效流程:渲染 101 集群加速实战​
  • 硬件产品的技术资料管控是确保研发可追溯、生产可复制、质量可控制的核心环节。
  • Linux 716 数据库迁移
  • NodeJS Express 静态文件、中间件、路由案例
  • iPhone 数据擦除软件评测(最新且全面)
  • 为什么要使用nginx?
  • 网络基础10 业务访问控制--ACL与包过滤
  • springboot如何redis锁
  • python学习---dayday6
  • 基于华为欧拉系统安装FileGator文件管理器
  • git本地的操作
  • Java 增强 switch 语句详解:从基础到进阶的全面指南
  • 基于conda包的环境创建、激活、管理与删除
  • 如何卸载SQLServer
  • MybatisPlus由浅入深
  • Neo4j Python 驱动库完整教程(带输入输出示例)
  • Supervisor 使用教程:进程守护的最佳实践指南
  • 06-C语言:第06天笔记
  • 数据分析与AI丨从传感器到智能决策:数据驱动企业发展与 ESG 创新的全链路实践
  • 18.理解 Python 中的切片赋值
  • OpenCV-Python Tutorial : A Candy from Official Main Page(三)
  • Redis原理之持久化