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 ライブラリが付属しており、クライアント/サーバー アーキテクチャを使用して、2 つのプロセス間の通信を HTTP で動作するように設定できます。この場合、現在不必要に多くの CPU サイクルを使用しているビジー待機を回避できます。

  2. はるかに簡単な解決策は、組み込みのsleep/1述語の呼び出しを挿入してプロセスをスリープ状態にしてから、ファイルを再度開くことです。たとえばsleep(1)、プロセスを 1 秒間スリープ状態にするために使用します。

  3. たとえばprocess_wait/2、呼び出されたプロセスが終了してファイルを生成するまで待機するために使用します。

あなたが説明していることから、(2)はうまくいき、(3)は少しエレガントで、(1)はより困難なケースのために一般的に知っておくとよいかもしれません。

于 2016-07-01T06:04:38.500 に答える