Difference between revisions of "Mutex.InitializeSeparateProcess"
1>Admin (→Примеры) |
m (1 revision imported) |
(No difference)
|
Latest revision as of 10:46, 9 August 2022
InitializeSeparateProcess (Работа с подчиненными процессами) | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Функция создает новый процесс для указанного в аргументе модуля (или текущего, если модуль не указан). Процесс может быть создан как для визуального, так и для консольного клиента. Новый процесс создается невидимым, и регистрируется в той же самой базе данных, для той же учетной записи, что и вызывавший процесс. Работа визуальных функций в новом процессе не поддерживается (процесс будет считаться консольным даже если он запущен в визуальном клиенте).
Функции, выполняющиеся в отдельных процессах, могут использоваться для изолирования кода исполнения, к примеру когда внешняя библиотека (или OLE объект) работают со сбоями и могут испортить системную память, тем самым вызывая завершение с ошибкой всего процесса клиента. После инициализации, процесс будет находиться в режиме ожидания исполнения, клиент же может периодически вызывать функцию InterProcessExecuteFunction для исполнения программы в ожидающем процессе. После удаления объекта семафора из системы, подчиненный процесс также будет завершен. Исполнение всегда происходит в синхронном режиме (функция InterProcessExecuteFunction ожидает окончания исполнения удаленной функции и только после этого возвращает результат), асинхронный режим для большей гибкости при работе планируется в будущем.
При работе с функциями подчиненным процессов необходимо знать:
- При создании подчиненного процесса, глобальные модули будут инициализированы, как для обычного процесса. Для ускорения инициализации, разработчик может предусмотрительно не загружать объекты, не имеющие значения в работе подчиненного процесса. Чтобы отличить обычный рабочий режим от режима подчиненного процесса, необходимо использовать функцию IsExecutingInSeparateProcess. Если в проекте используются разные подчиненные процессы, можно предусмотреть различные методы инициализации глобальных модулей, используя идентификаторы процесса, задаваемые в текущей функции. Идентификатор можно получить, используя ту же функцию IsExecutingInSeparateProcess.
- Подчиненный процесс также может инициализировать свои потоки (и даже свои подчиненные процессы). Однако, нужно понимать, что основной поток, работающий в синхронном режиме с процессом-родителем, вне исполнения функций всегда находится в режиме ожидания задачи от процесса-родителя.
- После загрузки и инициализации глобальных модулей, подчиненный процесс получает модуль, из которого будут исполняться функции с помощью метода InterProcessExecuteFunction. Данный модуль не запускается на исполнение, поэтому, переменные этого модуля не будут доступны при вызове его функций. Глобальные переменные, однако, будут работать как обычно.
- Каждый новый процесс добавляет в систему большое количество потоков, семафоров и событий и пр. Создание большого количества таких процессов, может привести высокому использованию ресурсов операционной системы. Особенно это может сказаться на терминальных серверах. Необходимо понимать это, при использовании подчиненных потоков.
Синтаксис
Mutex.InitializeSeparateProcess(<Идентификатор процесса (STRING)>,<Скомпилированная функция или текст модуля (STRING, COMPILEDFUNCTION)>):<Указатель на среду процесса (MUTEX)>
Аргументы
<Идентификатор процесса (STRING)>
- (необязательный аргумент) Произвольная строка, которая может быть получена в подчиненном процессе с помощью функции IsExecutingInSeparateProcess.<Скомпилированная функция или текст модуля (STRING, COMPILEDFUNCTION)>
- (необязательный аргумент) Строковое выражение, являющееся кодом модуля, для которого в подчиненном процессе будут вызываться функции, либо объект типа компилированная функция. Если аргумент не указан, в подчиненный процесс будет экспортирован и передан текущий модуль (модуль, в котором располагается код, который вызвал данную функцию).
Возвращаемое значение
Возвращает объект семафора, указывающего на новый запущенный процесс. В дальнейшем этот объект можно использовать с функциями, типа TerminateProcess. Если процесс не удалось запустить, по каким-либо причинам, функция, либо вызывает исключение, либо отдает объект, для которого функция IsProcessActive возвращает ноль.
Примеры
Function ИсполнитьВДругомПроцессе(спДанные,ByRef Переменная,ByRef Переменная2=0) спДанные["Значение"]:=10; Переменная:=20; Переменная2:=30; Result:=40; EndFunction аПроцесс:=Mutex.InitializeSeparateProcess(); спДанные:=List.Create(); спДанные["Значение"]:=1; Переменная:=2; //Будет выведено 40 Message(аПроцесс.InterProcessExecuteFunction("ИсполнитьВДругомПроцессе",спДанные,Переменная)); //Будет выведено 20 Message(Переменная); //Будет выведено 1, так как спДанные не имеет отметки ByRef (см. рекомендации в описании InterProcessExecuteFunction) Message(спДанные["Значение"]);