16

我正在使用命名管道在另一个程序(MATLAB)中捕获外部程序(wgrib2)的输出。MATLAB 代码如下,并system()访问命令行来制作管道:

system('mkfifo myfifo');     % Make a named pipe myfifo
% Call the external program wgrib2 and dump its output to the named pipe myfifo
system('wgrib2.exe multi_1.glo_30m.hs.201212.grb2 -ij 1 165 -ij 1 166 > myfifo &');
fid = fopen('myfifo', 'r');  % Open the named pipe
a = fscanf(fid, '%c');       % Read the output as character
fclose(fid);                 % Close the "file" (myfifo still exists afterward)

以下是我的问题:

  1. myfifo使用命名管道后是否必须关闭它?代码运行后它似乎仍然存在。
  2. 如果myfifo需要关闭,关闭它的命令是什么?
  3. 我将多次运行上面的代码示例(> 1000),所以如果我重用命名管道并且直到结束才关闭它可以吗?
4

4 回答 4

11
  1. 不,Unix 将所有内容都视为文件。命名管道没有什么不同。如果你用完了它,你可能想要关闭它,这样你就不会用命名管道弄乱你的机器,但你不需要关闭它。

编辑以反映以下评论,这是正确的。删除!=关闭。

  1. 关闭命名管道的方式与关闭任何文件的方式相同:
    fclose(mFifo)

正如接受的答案中提到的,关闭不会删除先进先出。您可能需要单独执行此操作。

  1. 重用命名管道没有任何问题。但是,由您决定何时完成每次迭代的读/写操作。一旦从管道中读取了所有数据,您就可以随意多次使用它。
于 2013-02-01T15:04:15.230 回答
2

您可能将关闭与mkfifo命令的反义词混淆了。

一个公认的答案对于 MATLAB 用户来说绝对是最好的解决方案,但我想为那些来到这里寻找命名管道的人澄清一下。


在类 Unix 上,命名管道 (FIFO) 是一种特殊类型的文件,没有内容。该mkfifo命令在文件系统上创建管道(为其分配名称),但不打开它。您需要像任何其他文件一样单独打开和关闭它。

  1. myfifo使用命名管道后是否必须关闭它?代码运行后它似乎仍然存在。

一旦您不再需要它们,通常最好关闭/删除/释放它们。
当所有描述符都关闭时,管道本身(及其内容)会被破坏。你看到的只是一个名字。

  1. 如果myfifo需要关闭,关闭它的命令是什么?

命名管道可以用fclose()function关闭。要使管道在给定名称下匿名且不可用(可以在管道仍然打开时完成),您可以使用 MATLAB 的delete函数rm控制台命令。

  1. 我将多次运行上面的代码示例(> 1000),所以如果我重用命名管道并且直到结束才关闭它可以吗?

只要每次迭代都以空管道开始,就可以重用命名管道(根据 MA​​TLAB 文档,fscanf()函数将为您执行此操作)。

命名管道可以通过两种方式重用:

  • 通过重用管道本身(不关闭它):
    system('mkfifo myfifo');
    tmp = fopen('myfifo', 'r+'); % Open the pipe in both ways (otherwise it will block)
    fid = fopen('myfifo', 'r');  % Open the pipe for reading (otherwise `fscanf` will block)
    fclose(tmp);                 % Close the auxiliary descriptor
    
    % Use the pipe multiple times...
    system('wgrib2.exe multi_1.glo_30m.hs.201212.grb2 -ij 1 165 -ij 1 166 > myfifo');
    a = fscanf(fid, '%c');
    ...
    
    % Close and delete the pipe
    fclose(fid);
    delete myfifo;
    
  • 通过重用名称来打开管道(您使用它的方式)。
于 2021-05-15T19:16:49.483 回答
1

您可能不应该使用命名管道来捕获 MATLAB 中的系统输出。根据MA​​TLAB 的system()文档,您可以直接在system()调用中捕获输出:

[status, cmdout] = system('wgrib2.exe multi_1.glo_30m.hs.201212.grb2 -ij 1 165 -ij 1 166');
a = cmdout

但是,如果您坚持使用命名管道,那么是的,您应该关闭它。您应该始终关闭您打开的资源。但是关闭命名管道 不会删除它。

于 2017-03-15T15:58:22.020 回答
0

不能同意。您通过关闭它来关闭fifo。系统完成后关闭 fifo(上面的 system() 调用)。当fifo关闭时,另一方知道没有更多数据(EOF条件,示例代码中没有明确的EOF检查,但在真实代码中很可能)并完成。

于 2016-07-28T02:51:41.693 回答