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

目录

程序间调用的优势之一

1、Shell脚本

脚本功能说明:

执行效果

使用方法:

[2、Python 脚本 (python.py)](#2、Python 脚本 (python.py))

功能说明:

使用方法:

输出:

[3、C++ 程序 (test.cc)](#3、C++ 程序 (test.cc))

功能说明:

编译与运行:

输出:

4、三者的对比总结

补充说明

程序替换

[C 程序 (proc.c)](#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)系统调用获取子进程的退出状态。这种机制实现了程序间的调用与切换。

cpp 复制代码
pid_t id = fork();
if (id == 0){
	execvp(myargv[0], myargv);
	exit(1);
}

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

cpp 复制代码
wait(&status);
waitpid(id, &status, 0);

程序间调用的优势之一

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

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

1、Shell脚本

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

bash 复制代码
#!/bin/bash

i=0
while [ $i -le 10 ]
do
    echo "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=0i=10),每行格式为 hello shell: 后跟当前循环计数器的值。

使用方法:

  1. 将脚本保存为 test.sh

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

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

输出示例:

2、Python 脚本 (python.py)

bash 复制代码
#!/usr/bin/python

print("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)

cpp 复制代码
#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++):

    bash 复制代码
    g++ test.cc -o test
  3. 运行生成的可执行文件:

    bash 复制代码
    ./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)

cpp 复制代码
#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 程序

    bash 复制代码
    gcc proc.c -o proc
  2. 运行程序

    bash 复制代码
    ./proc
  3. 输出示例

调用shell脚本运行结果:

调用python运行结果:

调用C++运行结果:

对比表格

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

总结

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

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

相关推荐
对你无可奈何1 小时前
关于Ubuntu的 update造成的内核升级
运维·服务器·ubuntu
qq_312920111 小时前
Nginx限流与防爬虫与安全配置方案
运维·爬虫·nginx·安全
GanGuaGua1 小时前
Linux系统:线程的互斥和安全
linux·运维·服务器·c语言·c++·安全
lsnm2 小时前
【LINUX网络】IP——网络层
linux·服务器·网络·c++·网络协议·tcp/ip
全糖去冰吃不了苦2 小时前
ELK 集群部署实战
运维·jenkins
不掰手腕2 小时前
在UnionTech OS Server 20 (统信UOS服务器版) 上离线安装PostgreSQL (pgsql) 数据库
linux·数据库·postgresql
Lynnxiaowen2 小时前
今天继续昨天的正则表达式进行学习
linux·运维·学习·正则表达式·云计算·bash
努力学习的小廉2 小时前
深入了解linux系统—— POSIX信号量
linux·运维·服务器
刘一说2 小时前
CentOS部署ELK Stack完整指南
linux·elk·centos
从零开始的ops生活3 小时前
【Day 50 】Linux-nginx反向代理与负载均衡
linux·nginx