首页 文章

GNU Octave中的Mkfifo

提问于
浏览
0

我还没有找到在线使用 mkfifo() 功能的完整示例 . 我可以像这样制作fifo:

mkfifo("file",777)

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

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

2 回答

  • 0

    有两个问题 . 首先: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的另一端连接起来 .

  • 0

    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));
    

相关问题