我正在使用命名管道(fifo)在python和MATLAB之间进行通信。从管道读取的MATLAB代码是可用的,但如果没有写入fifo,它就会挂起。我希望在没有可用数据的情况下优雅地超时。
如果管道存在(在bash中):
$ mkfifo pipe_read
但MATLAB打开命令没有数据:
>> fid = fopen('pipe_read', 'r');
挂起,直到数据可用:
$ echo "test data" >> pipe_read
如果没有数据可用,我希望fopen
返回一个指示错误的文件ID(即类似于文件不存在时的-1),而不是永久阻止。
是否有类似于编写和读取串行乐器的命令中可用的异步读取的解决方案:http://www.mathworks.com/help/matlab/ref/readasync.html?
或者可能fopen
可以嵌入到启用超时的matlab计时器对象中?
以前曾经问过但没有回答: Matlab read from named pipe (fifo)
答案 0 :(得分:2)
我很确定这个问题实际上不是Matlab的fopen
,而是潜在的open
系统调用。通常,管道或FIFO的使用仅在存在读取器和写入器时才有意义,因此,默认情况下,open(2)
将阻塞,直到FIFO的另一端也被打开。
我不认为将fopen
调用嵌入到任何其他Matlab对象中会起作用。据我所知,避免这种情况的唯一方法是编写自己的fopen
版本,作为专门的Mex函数。在这种情况下,您可以使用open(2)
标记O_NONBLOCK
来调用or
,并使用您想要的任何读/写标记。但是在man 2 open
部分的ERRORS
下挖掘,如果" ENXIO
和O_NONBLOCK
是{#1}},则可以看到O_WRONLY
被返回设置,该文件是一个FIFO,没有任何进程打开它来读取"。这意味着你需要确保Python在 Matlab尝试打开以进行写入之前打开了用于读取的FIFO(反之亦然)。
最后一点,请记住,Matlab的fopen
返回文件描述符的句柄。您的Mex功能可能应该反映出来,因此您可以毫无问题地将其传递到fread
/ fscanf
/等。
答案 1 :(得分:0)
在Linux中,使用timeout
进行系统调用将达到目的。例如:
timeout = 5; % timeout in seconds
pipe = 'pipe_read';
[exit_code,str] = system(sprintf('timeout %ds cat %s', timeout, pipe));
switch(exit_code);
case 0; doSomething(str); % found data
case 124; doTimeout(); % timedout
end
MacOS的gtimeout
与我类似。