是否应该关闭用mkfifo打开的命名管道?

时间:2013-02-01 14:55:49

标签: pipe mkfifo

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

  1. 使用后我是否必须关闭命名管道myfifo?代码运行后似乎仍然存在。
  2. 如果需要关闭myfifo,关闭它的命令是什么?
  3. 我将在下面多次运行代码示例(> 1000),如果我重复使用命名管道并且直到最后才关闭它,这样可以吗?
  4. 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)
    

4 个答案:

答案 0 :(得分:10)

  1. 否。 Unix将所有内容视为文件。命名管道没有什么不同。如果你已经完成了它的使用,你可能想关闭它,这样你就不会使用命名管道弄乱你的机器,但你不需要关闭它。
  2. 编辑以反映以下评论,这是正确的。删除!=关闭。

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

      如接受的答案所述,结束不会删除fifo。您可能需要单独执行此操作。

      1. 重新使用命名管道没有任何问题。但是,您可以知道每次迭代完成读/写操作的时间。一旦从管道中读出所有数据,您可以根据需要再次使用它。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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


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

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

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

<块引用>
  1. 如果myfifo需要关闭,关闭它的命令是什么?

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

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

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

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

  • 通过重用管道本身(不关闭它):
    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;
    
  • 通过重用名称来打开管道(您使用它的方式)。

答案 3 :(得分:0)

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