Обработка исключений файлов и ожидание процесса в SWI Prolog

Я выполняю свой код на 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)

Поэтому, в качестве обходного пути, я пытаюсь отловить ошибку, обработать ее, сравнивая с "creation_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. Я пытался использовать его, но он дает ошибку.

Любая помощь или рекомендации с благодарностью.

1 ответ

У вас есть несколько вариантов решения этой проблемы:

  1. Вы можете полностью пересмотреть способ взаимодействия этих процессов. Например, SWI-Prolog поставляется с очень мощными библиотеками HTTP, и вы можете настроить связь между двумя процессами для работы по HTTP, используя архитектуру клиент / сервер. В этом случае вы избегаете ожидания занятости, которое в настоящее время использует много циклов ЦП без необходимости.

  2. Гораздо более тривиальное решение - просто вставить вызов встроенного sleep/1 предикат, чтобы перевести процесс в спящий режим, прежде чем пытаться снова открыть файл. Использовать например sleep(1) уложить процесс на 1 секунду.

  3. Использовать например process_wait/2 подождать, пока вызванный процесс завершит работу и сгенерирует файл.

Из того, что вы описываете, похоже, что (2) будет делать, (3) немного более элегантно, и (1) может быть полезно знать в целом, для более сложных случаев.

Другие вопросы по тегам