【问题标题】:Mkfifo in GNU OctaveGNU Octave 中的 Mkfifo
【发布时间】:2015-05-07 19:46:40
【问题描述】:

我还没有找到在线使用mkfifo() 函数的完整示例。我可以像这样制作先进先出:

mkfifo("file",777)

但是当我fopen() 这个文件时,Octave 就挂了。从mkfifo 对象创建、排队和出列字节的正确方法是什么?

我想在 Octave 中创建一个内存中的 fifo(在磁盘上也可以),并从同一个 Octave 脚本中读取和写入它。我的项目是实时运行的,所以我需要一个缓冲区,以便我可以从同一个 Octave 脚本中填充和排出。我搜索了一个结果为零的 fifo 库。即使只是创建一个向量并推送和弹出也可以满足我的需求。我自己尝试过,但我遇到了面向对象的编程设计问题,因为 Octave 不允许通过引用或指针传递。

【问题讨论】:

    标签: octave


    【解决方案1】:

    有两个问题。第一:mkfifo 期望模式为以 10 为底的整数,如果你写“777”,你认为是八进制,以 8 为底。第二:mkfifo 使用 umask 将权限修改为 (mode & ~umask)(参见 man 3)

    例如:

    fn=tempname
    [ERR, MSG] = mkfifo (fn, base2dec("744", 8))
    stat(fn)
    fn = /tmp/oct-83UCBR
    ERR = 0
    MSG = 
    ans =
    
      scalar structure containing the fields:
    
    dev =  2053
    ino =  3408172
    mode =  4580
    modestr = prwxr--r-- 
    nlink =  1
    uid =  1000
    gid =  1000
    rdev = 0
    size = 0
    atime =    1.4311e+09
    mtime =    1.4311e+09
    ctime =    1.4311e+09
    blksize =  4096
    blocks = 0
    

    如您所见,modestr 现在是 prwxr--r-- 正如您对八进制 744 所期望的那样

    现在您可以打开 FIFO 的一端:

    fid = fopen (fn, "r")
    

    当然,这会阻塞,直到 fifo 的另一端连接为止。

    【讨论】:

    • @portforwardpodcast:“八度挂起”是 fopen 的预期阻塞,直到另一端连接(因为它在没有 O_NONBLOCK 的情况下打开)
    • 是的,很多东西都不清楚和缺失。据此:octave.1599824.n4.nabble.com/filesize-of-fifo-td1613956.html 我需要在打开文件后立即调用fcntl(fid, F_SETFL, O_NONBLOCK); 进行阅读。但是该行永远不会运行,因为在作者到达之前打开文件进行读取时我被阻止了。
    • 为了清楚起见,我需要从同一个脚本中读取和写入这个 fifo,我编辑了我的问题以更清楚
    【解决方案2】:

    fifo 类有效,但只能达到一定的大小。 fifo 的最大字节数可以通过运行找到:

    cat /proc/sys/fs/pipe-max-size
    1048576
    

    下面是我为内存 fifo 编写的代码。它相当粗糙,但效果很好:

    1; % Prevent Octave from thinking that this is a function file
    
    global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
    fifoSamples = zeros(0);
    fifoCount = 0;
    fifoFiles = cell(1);
    fifoFids  = zeros(0);
    fifoDataType = 'single';
    fifoDataTypeSize = 4;
    fifoMaxBytes = 1048576; % this is operating system enforced, changing here will not help
    
    function [] = o_fifo_write(index, data)
        global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
    
        wrcount = fwrite(fifoFids(index), data, fifoDataType);
    
        [sz,~] = size(data);
    
        fifoSamples(index) = fifoSamples(index) + sz;
    
        if( sz ~= wrcount )
            disp(sprintf('o_fifo_write was given %d samples but wrote %d', sz, wrcount));
        end
    
        if( ~iscolumn(data) )
            disp('data must be columnar in o_fifo_write');
        end
    end
    
    function [data] = o_fifo_read(index, count)
        global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
    
        [data, rdcount] = fread(fifoFids(index), count, fifoDataType);
    
        [sz,~] = size(data);
    
        fifoSamples(index) = fifoSamples(index) - sz;
    
        if( sz ~= rdcount || sz ~= count )
            disp(sprintf('in o_fifo_read %d %d %d should all be the same', sz, rdcount, count));
        end
    end
    
    function [avail] = o_fifo_avail(index)
        global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
    
        avail = fifoSamples(index);
    end
    
    function index = o_fifo_new()
        global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
    
        fifoCount = fifoCount + 1;
        index = fifoCount;
    
        fifoSamples(index) = 0;
        fifoFiles{index} = tempname;
        [ERR, MSG] = mkfifo(fifoFiles{index}, base2dec('744',8));
        fifoFids(index)  = fopen(fifoFiles{index}, 'a+');
    %     fcntl(fifoFids(index), F_SETFL, O_NONBLOCK);  % uncomment to avoid hangs when trying to overfill fifo
    end
    
    
    % ---- usage -----
    
    txfifo = o_fifo_new();
    disp(o_fifo_avail(txfifo));
    o_fifo_write(txfifo, [1.243 pi 2*pi 4/3*pi]');
    disp(o_fifo_avail(txfifo));
    disp(o_fifo_read(txfifo, 4));
    disp(o_fifo_avail(txfifo));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多