Octave GNU倍频程中的Mkfifo

Octave GNU倍频程中的Mkfifo,octave,Octave,我还没有找到在线使用mkfifo()函数的完整示例。我可以使fifo如下所示: mkfifo("file",777) 但是当我fopen()这个文件时,Octave就挂起了。从mkfifo对象创建、排队和出列字节的正确方法是什么 我想创建一个八度内存fifo(在磁盘上也可以),并从同一个八度脚本读写它。我的项目是实时运行的,所以我需要一个缓冲区,这样我就可以从同一个八度脚本中填充和排出。我搜索了一个没有结果的fifo库。即使只是创建一个向量,并推动和弹出将适合我的需要。我自己也尝试过,但我遇到

我还没有找到在线使用
mkfifo()
函数的完整示例。我可以使fifo如下所示:

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


我想创建一个八度内存fifo(在磁盘上也可以),并从同一个八度脚本读写它。我的项目是实时运行的,所以我需要一个缓冲区,这样我就可以从同一个八度脚本中填充和排出。我搜索了一个没有结果的fifo库。即使只是创建一个向量,并推动和弹出将适合我的需要。我自己也尝试过,但我遇到了面向对象编程设计问题,因为Octave不允许通过引用或指针传递。第一: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的另一端连接。

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

@portforwardpodcast:“倍频程挂起”是fopen的预期阻塞,直到另一端连接(因为它是在没有O_NONBLOCK的情况下打开的)是的,有很多是不清楚和缺失的。根据这个:我需要调用
fcntl(fid,F_SETFL,O_NONBLOCK)打开文件进行读取后立即执行。但这一行永远不会运行,因为在编写者到达之前打开文件阅读时,我被阻止了。为了清楚起见,我需要从同一个脚本读写fifo,我编辑了我的问题以使其更清晰