2

我在 SWI Prolog 和 Windows 7 上运行我的代码。在我的代码中,我使用 'win_exec()' 调用另一个应用程序(我尝试使用方法 'shell()',但它不起作用。),并且在end 在文本文件中生成其输出。但是有时它会运行 30 分钟。现在我的序言代码使用这个输出文本文件,进一步解析和处理它。这是我用来调用其他应用程序然后使用其输出文件的代码:

main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
                 open('C:\\myfolder\\outputfile.txt', read, Mf),
                 read_file(Mf, X),  % PROCEDURE TO READ FILE CONTENTS 
                 close(Mf),
                 statistics(cputime, Value). % CALCULATE HOW LONG IT TOOK

但是,由于该文件尚未由另一个应用程序输出,因此会出现错误:

ERROR: open/4: source_sink `C:\myfolder\outputfile.txt' does not exist (No such file or directory)

因此,作为一种解决方法,我尝试捕获错误,通过与“existence_error”进行比较来处理它,然后递归调用 open 过程,直到它最终成功,即其他应用程序已完成其处理并生成输出文件。这是我的解决方法代码:

main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
                 open_output(X),   % PROCEDURE FOR FILE EXCEPTION HANDLING
                 statistics(cputime,Value).

open_output(X) :- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,X), close(Mf)),
                         error(Err,Context),
                         open_output_aux(Err,X)). % AUX PROCEDURE TO RECOVER

% Write some code here
% open_output_aux code matches the error code with 'existence_error';
% if true, calls open_aux_wait procedure; else throw the error.

open_aux_wait(Z):- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,Z), close(Mf)),
                   error(Err,Context),
                   open_aux_wait(Z)).

然而,这样做似乎效率很低。我想知道是否有更好的方法来做到这一点,比如在 java 中,你可以在处理文件异常时简单地调用 wait() 。在文档中,有一个方法“wait_for_input\3”,但它说“wait_for_input()”不能用于 Windows 中的文件流。我尝试使用它,但它给出了错误。

非常感谢任何帮助或指导。

4

1 回答 1

2

你有几个选项来解决这个问题:

  1. 您可以完全重新考虑这些进程的通信方式。例如,SWI-Prolog 带有非常强大的 HTTP 库,您可以使用客户端/服务器架构设置两个进程之间的通信以通过 HTTP 工作。在这种情况下,您可以避免当前不必要地使用许多 CPU 周期的忙碌等待。

  2. sleep/1一个更简单的解决方案是在尝试再次打开文件之前简单地插入内置谓词的调用以使进程进入睡眠状态。例如使用sleep(1)让进程休眠 1 秒。

  3. 例如process_wait/2,用于等待被调用进程完成并生成文件。

根据您的描述,看起来(2)会做,(3)稍微优雅一些​​,并且(1)对于更困难的情况可能一般都很好。

于 2016-07-01T06:04:38.500 回答