如何在 IDL Spawn 命令中访问 Python 标准流?

How to access Python standard stream in IDL Spawn command?

我有一个这样的 python 程序:

raw_data = sys.stdin.buffer.read(nbytes) # Read from standard input stream
# Do something with raw_data to get output_data HERE...
output_mask = output_data.tostring() # Convert to bytes
sys.stdout.buffer.write(b'results'+output_mask) # Write to standard output stream

然后我使用 Pyinstaller 得到这个 python 程序的 my_py.exe。我在 Python 中使用 subprocess.run() 测试 my_py.exe。还好。

但是,我需要在 IDL 中调用这个 my_py.exe。 IDL this tutorial 关于如何将其 SPAWN 命令用于管道。所以我调用 my_py.exe 的 IDL 程序是这样的:

SPAWN['my_py.exe', arg], COUNT=COUNT , UNIT=UNIT

WRITEU, UNIT, nbytes, data_to_stream

READU, UNIT, output_from_exe

不幸的是,上面的 IDL 程序在 READU 处挂起。有谁知道我在这里遇到的问题?是我的python读写有问题吗?

您在 SPAWN 命令中遗漏了一个逗号,尽管我想如果您的代码中存在该拼写错误,IDL 会在您到达 READU 之前发出语法错误。但是,如果由于某种原因 IDL 通过错误的 SPAWN 调用悄悄地继续执行,可能 READU 挂起,因为它试图读取一些无意义的逻辑单元。无论如何,它应该是:

SPAWN,['my_py.exe', arg], UNIT=UNIT

完整语法供参考:

SPAWN [, Command [, Result] [, ErrResult] ]

Keywords (all platforms): [, COUNT=variable] [, EXIT_STATUS=variable] [ ,/NOSHELL] [, /NULL_STDIN] [, PID=variable] [, /STDERR] [, UNIT=variable {Command required, Result and ErrResult not allowed}]

UNIX-Only Keywords: [, /NOTTYRESET] [, /SH]

Windows-Only Keywords: [, /HIDE] [, /LOG_OUTPUT] [, /NOWAIT]

我已经删除了 COUNT 关键字,因为根据 documentation,COUNT 包含结果中的行数,如果 结果存在,它不是。事实上,这里甚至不允许使用 Result,因为您使用的是 UNIT 关键字。我怀疑传递 COUNT 关键字会导致 READU 挂起,但这是不必要的。

此外,请查看文档中的这条注释 确保您作为命令传递的数组是正确的:

If Command is present, it must be specified as follows:

On UNIX, Command is expected to be scalar unless used in conjunction with the NOSHELL keyword, in which case Command is expected to be a string array where each element is passed to the child process as a separate argument.

On Windows, Command can be a scalar string or string array. If it is a string array, SPAWN glues together each element of the string array, with each element separated by whitespace.

我不知道你的代码的细节,但这里有一些更大胆的猜测:

  • 你可以尝试设置NOSHELL关键字,就像在黑暗中拍摄一样。

  • 我偶尔会遇到这样的问题,即当我没有关闭文件单元时 IDL 似乎没有完成写入磁盘,所以请确保你在 [=11] 之后使用 FREE_LUN, UNIT =].我知道你说它在 READU 处挂起,但我的想法是 可能 它只是看起来挂起,并且在文件单元关闭之前无法继续。

最后,这可能是真正的问题,值得研究(来自您链接到的教程):

A pipe is simply a buffer maintained by the operating system with an interface that makes it appear as a file to the programs using it. It has a fixed length and can therefore become completely filled. When this happens, the operating system puts the process that is filling the pipe to sleep until the process at the other end consumes the buffered data. The use of a bidirectional pipe can lead to deadlock situations in which both processes are waiting for the other. This can happen if the parent and child processes do not synchronize their reading and writing activities.