Matlab read from fifo with fopen timeout

人走茶凉 提交于 2020-01-05 05:52:30

问题


I'm working with named pipes (fifo) to communicate between python and MATLAB. The MATLAB code to read from the pipe is functional but it hangs if nothing has been written to the fifo. I would prefer it would gracefully timeout when no data is available.

If the pipe exists (in bash):

$ mkfifo pipe_read

but has no data the MATLAB open command:

>> fid = fopen('pipe_read', 'r'); 

hangs until data is available:

$ echo "test data" >> pipe_read

Rather than blocking forever I would like fopen to return a file-id that indicates an error (i.e. similar to -1 as it does when the file does not exist) if there is no data available.

Could there be a solution similar to the asynchronous reads available in the commands for writing and reading to serial instruments: http://www.mathworks.com/help/matlab/ref/readasync.html ?

Or possibly fopen could be embedded into a matlab timer object that enables a timeout?

This has been asked before but without an answer: Matlab read from named pipe (fifo)


回答1:


I'm pretty sure the issue is not actually with Matlab's fopen, but the underlying open system call. Generally, the use of a pipe or FIFO only makes sense when there exists both a reader and a writer, and so, by default, open(2) will block until the other end of the FIFO has been opened as well.

I don't think it will work to embed the fopen call in any other Matlab object. As far as I'm aware, the only way to circumvent this is to write your own version of fopen, as a specialized Mex function. In this case, you can make a call to open(2) with the O_NONBLOCK flag or'd with whatever read/write flag you'd like. But digging around in man 2 open, under the ERRORS section, you can see that ENXIO is returned if "O_NONBLOCK and O_WRONLY are set, the file is a FIFO, and no process has it open for reading". That means you need to make sure that Python has opened the FIFO for reading before Matlab tries to open for writing (or vice versa).

As a final point, keep in mind that Matlab's fopen returns a handle to a file descriptor. Your Mex function should probably mirror that, so you can pass it around to fread/fscanf/etc without issues.




回答2:


In Linux, a system call with timeout would do the trick. For example:

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 has gtimeout which I assume is similar.



来源:https://stackoverflow.com/questions/25583670/matlab-read-from-fifo-with-fopen-timeout

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!