GNU Octave 中的 Mkfifo
Mkfifo in GNU Octave
我还没有找到在线使用 mkfifo()
功能的完整示例。我可以像这样制作 fifo:
mkfifo("file",777)
但是当我 fopen()
这个文件时,Octave 挂起。从 mkfifo
对象创建、排队和出队字节的正确方法是什么?
我想在 Octave 中创建一个内存中的 fifo(在磁盘上也可以)并从同一个 Octave 脚本中读取和写入它。我的项目是 运行 实时的,所以我需要一个缓冲区,以便我可以从同一个 Octave 脚本中填充和排出。我搜索了一个结果为零的 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 class 有效,但仅限于特定大小。 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));
我还没有找到在线使用 mkfifo()
功能的完整示例。我可以像这样制作 fifo:
mkfifo("file",777)
但是当我 fopen()
这个文件时,Octave 挂起。从 mkfifo
对象创建、排队和出队字节的正确方法是什么?
我想在 Octave 中创建一个内存中的 fifo(在磁盘上也可以)并从同一个 Octave 脚本中读取和写入它。我的项目是 运行 实时的,所以我需要一个缓冲区,以便我可以从同一个 Octave 脚本中填充和排出。我搜索了一个结果为零的 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 class 有效,但仅限于特定大小。 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));