Linux下Matlab R2017如何导入C程序无限printf输出并实现类FIFO功能?
解决Linux下Matlab R2017实时读取C程序输出的方案
刚好在Linux+Matlab R2017环境下处理过类似需求,给你两个靠谱的方案,都能实现实时捕获C程序的输出并存储为Matlab数组:
方案1:使用Linux命名管道(FIFO)实现实时读取
这是最贴近你提到的FIFO需求的方法,利用Linux原生的命名管道机制,让C程序的输出持续写入管道,Matlab从管道实时读取。
操作步骤:
创建命名管道
在Matlab命令行或者终端执行:!mkfifo /tmp/my_c_program_pipe这里用
/tmp目录是因为它是临时文件目录,能避免大部分权限问题。后台启动C程序并重定向输出到管道
同样在Matlab里执行(加&让程序后台运行,不阻塞Matlab的操作):!./prog > /tmp/my_c_program_pipe &Matlab实时读取管道内容
编写Matlab代码打开管道,循环读取输出并存储为数组:% 打开命名管道 fid = fopen('/tmp/my_c_program_pipe', 'r'); if fid == -1 error('无法打开命名管道,请检查路径和权限'); end % 初始化存储数组(根据你的输出格式调整,比如数值数组/字符串数组) output_array = []; % 循环读取直到管道关闭(C程序结束) while ~feof(fid) % 读取一行输出(如果你的C程序输出是单行数值/字符串) line_content = fgetl(fid); if ischar(line_content) && ~isempty(line_content) % 转换为数值(如果输出是数字,根据实际格式调整) num_val = str2double(line_content); if ~isnan(num_val) output_array = [output_array, num_val]; % 追加到数组 disp(['实时读取到:', num2str(num_val)]); end end % 加小延迟降低CPU占用 pause(0.1); end % 清理资源 fclose(fid); !rm /tmp/my_c_program_pipe % 可选:用完删除管道
关键注意事项:
你的C程序必须在每次printf后调用fflush(stdout),因为Linux下stdout默认是行缓冲的,如果没有换行或者缓冲未满,输出不会立刻写入管道。修改后的C代码示例:
#include <stdio.h> #include <unistd.h> int main() { int count = 0; while (1) { printf("%d\n", count++); // 输出换行触发行缓冲,或者不加换行但强制fflush fflush(stdout); // 强制刷新输出缓冲区,确保内容立刻写入管道 sleep(1); // 模拟持续输出 } return 0; }
方案2:利用Matlab的Java集成功能实时捕获输出
Matlab R2017自带Java运行环境,可以直接调用Java的Process类启动C程序并实时读取其stdout,不需要额外创建管道文件,更简洁。
Matlab代码示例:
% 启动C程序进程 cmd = './prog'; process = java.lang.Runtime.getRuntime().exec(cmd); % 获取进程的标准输出流 input_stream = process.getInputStream(); buffered_reader = java.io.BufferedReader(java.io.InputStreamReader(input_stream)); % 初始化存储数组 output_array = []; % 循环读取输出 while true line = buffered_reader.readLine(); if isempty(line) % 输入流为空,说明C程序已结束 break; end % 转换为数值(根据输出格式调整) num_val = str2double(line); if ~isnan(num_val) output_array = [output_array, num_val]; disp(['实时读取到:', num2str(num_val)]); end pause(0.1); end % 清理资源 buffered_reader.close(); input_stream.close(); process.waitFor(); % 等待进程完全终止
同样需要注意:
C程序里必须加fflush(stdout),否则输出会被缓冲,Matlab无法实时获取内容。
方案对比
- 命名管道方案:适合需要和其他Linux程序共享C程序输出的场景,逻辑清晰,依赖Linux原生机制。
- Java Process方案:完全在Matlab内部实现,不需要额外创建文件,代码更紧凑。
两种方案都能实现你要的“类似FIFO的实时输出捕获”,并将内容存储为Matlab数组,你可以根据自己的需求选择。
内容的提问来源于stack exchange,提问作者Nik Konst
相关产品推荐
相关产品推荐

