当前位置: 首页 > 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.xdnf.cn/news/1133047.html

相关文章:

  • MySQL 8.0 OCP 1Z0-908 题目解析(27)
  • 解决“Windows 无法启动服务”问题指南
  • 论文导读--PQ3D:通过分段级分组实现多模态特征融合和 MTU3D:在线查询表示学习与动态空间记忆
  • C# 8.0 创建一个简单的控制台应用程序
  • 使用 CrewAI 进行股票分析:自动化投资决策的新途径
  • YAML 自动化用例中 GET vs POST 请求的参数写法差异
  • 剑指offer64_圆圈中最后剩下的数字
  • 分块(chunked) vs 滑动窗口(windowed)
  • 力扣面试150(31/150)
  • Python爬虫实战:研究PyYAML库相关技术
  • 工作第一步建立连接——ssh
  • STM32硬件I2C的注意事项
  • UniApp 多端人脸认证图片上传实现
  • Sketch 与 Figma
  • 基于 Python/PHP/Node.js 的淘宝 API 商品数据抓取开发教程
  • 个人笔记(linux/sort与uniq命令)
  • [硬件电路-28]:从简单到复杂:宇宙、芯片与虚拟世界的共通逻辑
  • 快速掌握 Kafka:从核心概念到生产级部署指南
  • 网络安全初级(XSS-labs 1-8)
  • 基于Canal实现MySQL数据库数据同步
  • 数字IC后端培训教程之数字后端项目典型项目案例解析
  • 端侧推理软件栈
  • 智慧农业新图景:物联网如何精准守护作物生长​
  • FCN语义分割笔记(1)
  • XSS-labs 1-8关
  • 系统性学习C语言-第十八讲-C语言内存函数
  • 从零开始的云计算生活——番外4,使用 Keepalived 实现 MySQL 高可用
  • xss-lab1-8关
  • AWS ML Specialist 考试备考指南
  • Liunx练习项目6-创建dns服务器