«Проблема» асинхронности исполнения скриптов
Суть «проблемы». Скрипты могут быть вызваны из синтаксиса и наоборот. Однако важной особенностью здесь является параллельность (или асинхронность) выполнения вызванной программы. Так, например, синтаксис, вызывающий скрипт, не приостанавливается до окончания работы скрипта, а продолжает своё выполнение (см. Рис. 1). При таком параллельном (несогласованном, асинхронном) исполнении этих двух процессов, возможно возникновение ошибок, если в ходе выполнения процессы должны обмениваться данными. Например, синтаксис может попытаться обратиться к результатам работы скрипта в то время, когда второй ещё выполняется (результаты отсутствуют). В некоторых случаях возникновение ошибок будет вовсе не очевидным и пользователь будет озадачен тем, что программа работает без видимых сбоев, но даёт неверные результаты! Таким образом, при комбинировании синтаксиса и скриптов нужно учитывать указанное обстоятельство и составлять программу соответствующим образом.

Рис. 1. Синхронная (а) и асинхронная (б) схемы исполнения
Ниже приводятся комментарии Кирилла Орлова по данному вопросу:
- «Отношения между синтаксисом и скриптом, когда одно из них запускает другое, являются особой программистской темой. Она может заинтересовать, скорее, продвинутых пользователей, так как только они будут писать код, предусматривающий совместную работу синтаксиса и скрипта.
- Так как синтаксис исполняется ядром системы (оно ответственно за всю статобработку и преобразования и называется «SPSS Processor»), а скрипт исполняется совсем другим агентом — оболочкой, ответственной за поведение графического интерфейса (меню, и т.п.), то они могут работать независимо, но могут и прислушиваться друг к другу. Этот вопрос встает, когда синтаксис запускает скрипт или скрипт запускает синтаксис. (Синтаксис запускает скрипт командой SCRIPT. Скрипт запускает синтаксис командой objSpssApp.ExecuteCommands strCommand или парой родственных команд.)
- Могут быть два режима работы синтаксиса и скрипта, когда одно запускает другое. Один режим — согласованный (synchronous, не следует понимать как «одновременный»), когда одно запускает другое и приостанавливается, ожидая, когда то закончит исполняться. Другой режим — параллельный (asynchronous, не следует понимать как «разновременный»), когда одно, запустив другое, продолжает работу как ни в чем не бывало.
- Уточнение: скрипт, запуская синтаксис, может работать с ним в согласованном или параллельном режиме (вы должны написать True или False после команды — см. пункт 2). Синтаксис, запуская скрипт, работает с ним только в параллельном режиме.
- Преимущество согласованного соисполнения в том, что, если скрипт и синтаксис обмениваются какой либо информацией (напр. входящими или результатами) во время соисполнения, она синхронизована по времени, и оттого не может произойти ни недоразумений, ни сбоев. Но согласованное соисполнение хотя надежно, медленнее; более того, оно не всегда возможно (см. в частности, см. пункт 4).
- Параллельное соисполнение не тратит время на простои. Но, в ситуации обмена информацией, имеют место вышеупомянутые недоразумения между синтаксисом и скриптом относительно «свежести», синхронизованности того, что передается.
- В своей книге SPSS Programming and Data Management и этой странице, посвященной «проблеме асинхронности», Левек разьясняет «недоразумения» асинхронности и обсуждает, как можно сделать, чтобы в режиме параллельного соисполнения добиться правильно обмена информацией между синтаксисом и скриптом».
NB! Проблема полностью решена в версии SPSS 14.
Описание использованных файлов
Демонстрация проблемы
Возможные решения
Описание использованных файлов
Данный синтаксис и скрипт использованы для демонстрации проблемы асинхронного исполнения в SPSS. (на основе вопроса в новостную группу SPSS от Kai Borgolte, размещённого 16.08.1999).
**** test.sps ****
data list free / v1 to v3.
begin data
1 2 3
end data.
frequencies variables = v1 .
* Следующей строкой вызываем на исполнение скрипт, который должен создать файл test.inc, включающий команду «frequencies variables = v2».
script 'c:\temp\test.sbs'.
* Затем мы запускаем этот синтаксис чтобы получить частотное распределение переменной v2.
include 'c:\temp\test.inc' .
* удаляем этот файл, поскольку он больше не нужен.
erase file = 'c:\temp\test.inc'.
frequencies variables = v3.
**** c:\temp\test.sbs ****
Sub Main
Open "c:\temp\test.inc" For Output As #1
Print #1, "frequencies variables = v2 ."
Close #1
'Сообщение пользователю, что скрипт работает и файл создан.
MsgBox "test.sbs работает, файл test.inc создан"
End Sub
Демонстрация проблемы
Сохраните вышеприведённый скрипт и синтаксис в c:\temp\. Первый раз, когда вы запускаете синтаксис…
- Выводятся частоты переменной v1;
- Получаем сообщение, что скрипт работает и файл test.inc записан;
- Частоты переменной v2 не выводятся;
- Выводятся частоты переменной v3.
Когда посмотрим в лог, увидим ,что «that test.inc was not found» (не был найден) и, следовательно, не был удалён (потому что на самом он не существовал когда выполнялась эта строка синтаксиса!).
Однако, если загляните в директорию c:\temp, то увидите нужный файл. Он был создан после выполнения команды ERASE.
Теперь, если запустите синтаксис повторно, не удаляя файл test.inc вручную, программа сработает как и ожидалась, мы увидим таблички частот для всех 3 переменных.
Данный пример включает вызов скрипта из синтаксиса. Обратите внимание, что эта проблема также возникает и при вызове синтаксиса из скрипта.
Возможные решения
Версия SPSS 12
Скрипт, написанный Fabrizio Запуск скриптов из синтаксиса.sbs, предназначен для решения проблемы. Однако в этом файле скрипт может уйти в бесконечный цикл, если в конце файла синтаксиса будут оставлены пробелы. Скорректированная версия ( Запуск скриптов из синтаксиса2.sbs) избавляет нас от этой проблемы.
Удостоверьтесь, что test.sps загружен в активное окно синтаксиса, загрузите и выполните SyntaxScript2 и вы увидите, что синтаксис test.sps работает так, как и ожидалось. Таблицы построены для всех 3 переменных. Для регулярного вызова скрипта SyntaxScript2 удобно сделать кнопочку на панели инструментов, чтобы вызывать его одним нажатием. Очень просто.
У этого скрипта, конечно, существуют свои ограничения. В частности, когда один скрипт вызывает другой скрипт и передаёт ему аргумент, вызываемый скрипт должен использовать особый метод чтобы прочесть аргумент.
В некоторых случаях обойти проблему асинхронности позволяет программа, написанная Alexis-Michel Mugabushaka, которая находится в разделе Программы на Visual Basic странички скриптов.
Версия SPSS 13
Появление команды HOST, которая выполняет инструкции на уровне операционной системы, даёт новые пути обхождения проблемы асинхронности. См. второе издание книги «Программирование и управление данными в SPSS» (SPSS Programming and Data Management), которая свободно доступна для скачивания с веб-сайта SPSS.
Версия SPSS 14
Начиная с версии 14, в SPSS могут исполняться скрипты Питон (Python), они работают синхронно с файлом синтаксиса из которого вызваны. Таким образом, проблема сейчас решена. См. примеры синхронного выполнения Питон-скриптов: «Самонастраивающийся код».



