Este é o site histórico da documentação 4D. As documentações estão sendo movidas progressivamente para developer.4d.com |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v19.8
Processos 4D Preemptivos
|
Execução Preemptiva | |
4D Server | X |
4D remoto | X (com ServerNet únicamente - ver Nova capa de rede ServerNet (compatibilidade)) |
4D single-user | X |
Modo Compilado | X |
Interpretado | - |
Se o contexto de execução suporta o modo apropriativo e se o método for "thread seguro", um novo processo 4D lançado utilizando os comandos New process ou CALL WORKER ou do menu "Executar método" se executará em modo apropriativo.
De outro modo, se chamar [#cmd id="317"/] ou CALL WORKER em um contexto de execução que não é suportado (por exemplo em uma máquina remota 4D) o processo é sempre cooperativo.O código 4D pode ser executado em fio (thread) apropriativo só quando algumas condições específicas forem cumpridas. Cada parte do código executado (comandos, métodos, variáveis...) deve ser compatível com uma execução apropriativa. Os elementos que podem ser executados em fios apropriativos são chamados threads seguros e os elementos que não podem ser executados em fios apropriativos são chamados threads inseguros.
Nota: dado que um thread se maneja de forma independente a partir do método processo pai, toda a string de chamadas não deve incluir nenhum código thread inseguro, do contrário a execução apropriativa não será possível. Este ponto se discute no parágrafo Quando um processo é iniciado de forma preemptiva?.
A propriedade "segurança de fio" de cada elemento depende do elemento em si:
Basicamente, o código que se executa em thread apropriativos não podem ser chamados as partes com as interações externas, tal como o código plug-in ou as variáveis interprocesso. Os acessos aos dados, entretanto, são permitidos desde o servidor de dados 4D que suporta a execução apropriativa.
Como padrão, 4D executará todos os métodos de projeto em modo cooperativo. Se desejar se beneficiar da funcionalidade modo apropriativo, o primeiro passo consiste em declarar explícitamente todos os métodos que deseja que se iniciem em modo apropriativo sempre que for possível, ou seja, os métodos que considere capaz de executar em processo apropriativo. O compilador comprovará que estes métodos sejam na verdade thread seguro (ver Como escrever um código thread seguro para saber mais). Também pode desabilitar o modo apropriativo para alguns métodos, se for necessário.
Lembre que definir um método como apropriativo faz com que seja elegível para execução apropriativa,mas não garante que se execute realmente em modo apropriativo. Iniciar um proceso em modo apropriativo resulta de uma avaliação realizada por 4D respeito as propriedades de todos os métodos na cadeia de chamadas de processo (para saber mais, consulte Quando um processo é iniciado de forma preemptiva?).
Para declarar seu método de elegibilidade para o modo apropriativo, é necessário utilizar a opção de declaração Modo de execução no quadro de diálogo Propriedades de método:
As seguintes opções estão disponíveis:
Caso particular: se o método també tiver a propriedade Compartido entre componentes e base local (ver Definir as propriedades dos métodos de projeto), ao estabelecer a opção Indiferente se etiquetará automaticamente o método como thread não seguro. Se quiser que um método de componente compartido seja thread seguro, deve estabelecer explícitamente a opção Pode ser executado em processos apropriativos.
Quando exportar o código do método usando, por exemplo, METHOD GET CODE, a propriedade "preemptiva" é exportada no comentário "%attributes" com um valor de "capable" ou "incapable" (a propriedade não está disponível se a opção for "indiferente"). Os comandos METHOD GET ATTRIBUTES e METHOD SET ATTRIBUTES também obtém ou estabelecem o atributo "preemptivo" com um valor "auto", "seguro" ou "inseguro".
A tabela abaixo resume os efeitos das opções de declaração do modo preemptivo
A tabela abaixo resume os efeitos das opções de declaração do modo preemptivo:
Opção | Valor de propriedade Preemptiva (interpretado) | Ação Compilador | Etiqueta Interna (compilado) | Modo de Execução se chain chamada for thread-seguro Pode ser executado em processos preemptivos | capaz | Checa capacidade e retorna erros se incapaz | thread-seguro | Preemptivo |
Não pode ser executado em processos preemptivos | incapaz | Nenhuma avaliação | thread-inseguro | Cooperativo | ||||
Indifferent | indiferente | Avaliação mas erros não são retornados | thread-sesguro ou thread-inseguro | Se thread-seguro: preemptivo; se thread-inseguro: cooperativo; se chamado diretamente: cooperativo |
Lembrete: a execução apropriativa só está disponível em modo compilado.
Em modo compilado, quando for iniciado um processo criado pelos métodos New process ou CALL WORKER, 4D lê a propriedade apropiativa do método processo (também chamado método pai) e executa o processo em modo apropriativo ou cooperativo, em função desta propriedade:
A propriedade segurança de thread depende da cadeia de chamadas. Se um método com a propriedade declarada "capaz" chamar a um método thread inseguro em qualquer de seus subníveis, um erro de compilação será devolvido: se um método único em toda a cadeia de chamadas for thread inseguro, "contaminará" todos os outros métodos e a execução apropriativa será recusada pelo compilador. Um thread apropriativo só pode ser criado quando toda a cadeia for thread seguro e o método de processo tiver sido declarado "Pode ser executado em processo apropiativo".
Por outro lado, o mesmo método thread seguro pode ser executado em um thread apropriativo em uma cadeia de chamada e em thread cooperativo em outra cadeia de chamada.
Por exemplo, considere os métodos de projeto abaixo:
//MyDialog project method
//contém chamadas de interface: será internamente thread inseguro
$win:=Open window("tools";Palette form window)
DIALOG("tools")
//MyComp project method
//contém computação simples: será internamente thread seguro
C_LONGINT($1)
$0:=$1*2
//Projeto método CallDial
C_TEXT($vName)
MyDialog
//Projeto método CallComp
C_LONGINT($vAge)
MyCom($vAge)
Declaração e cadeia de chamadas | Compilação | Segurança de thread resultante | Execución | Comentario |
![]() | OK | ![]() | Preemptivo | CallComp é o método pai, declarado "capaz" de uso preemptivo; já que MyComp é internamente thread seguro, CallComp é thread seguro e o processo for preemptivo |
![]() | Error | ![]() | a execução é impossível | CallDial é o método pai, declarado "capaz"; MyDialog é "indiferente". Entretanto, já que MyDialog está internamente thread inseguro, contamina a string de chamadas. A compilação falha devido a um conflito entre a declaração deCallDial e sua capacidade real. A solução é modificar MyDialog para que seja thread seguro, de modo que a execução seja preemptiva, ou mudar a declaração de propriedade de CallDial para executá-lo como cooperativo. |
![]() | OK | ![]() | Cooperativo | Como CallDial se declara "incapaz" de uso preemptivo, a compilação é internamente thread inseguro, a execução sempre será cooperativa, qualquer que seja o estado de MyDialog. |
![]() | OK | ![]() | Cooperativo | Como CallComp é o método pai (a propriedade era "indiferente"), depois o processo é cooperativo mesmo se toda a string for thread seguro. |
![]() | OK | ![]() | Cooperativo | Como CallDial é o método pai (propriedad era "indiferente"), então o processo é cooperativo e a compilação exitosa. |
4D lhe oferece novas funcionalidades para identificar a execução cooperativa ou apropriativa para processos:
Tipo de processo | Icone |
Processo armazenado apropriativo | ![]() |
Processo worker apropriativo | ![]() |
Método Preemptivo Web | ![]() |
Método Preemptivo SOAP | ![]() |
Para ser thread seguro, um método deve respeitar as seguintes regras:
Nota:
-no caso de um método "Compartido por componentes e bancos de dados locais", a propriedade "Pode ser executado em processos preemptivos" deve ser selecionada.
Todos as declarações SQL são thread seguro. Código SQL inserido em blocos Begin SQL/End SQL devem comprir com as condições abaixo::
-deve aplicar ao Servidor 4D ou base local 4D ( ODBC ou bancos de dados remotos via SQL LOGIN são thread seguros. Entretanto, bancos locais usados com USE DATABASE são thread seguros)
Qualquer trigger chamado pela declaração SQL deve ser thread seguro (ver Triggers (disparadores)).
(*) Para intercambiar dados entre processos preemptivos (e entre todos os processos), pode passar coleções compartidas ou objetos compartidos como parâmetros a processos, ou usar o catálogo Storage. Para obter mais informação, consulte a página Objetos compartidos e Coleções compartidas.
Os processos worker também lhe permitem intercambiar mensagens entre processos, incluidos os processos preemptivos. Para mais informação, consulte Sobre Workers.
(**) O comando ClientComment oferece uma solução elegante para chamar a objetos de interface de um processo preemptivo.
Os métodos com a propriedade "Pode ser executado em processos preemptivos" serão verificados por 4D na etapa de compilação. Um erro de compilação se emite quando o compilador encontrar algo que lhe impeça ser thread seguro:
Nota: é possível desabilitar localmente a verificação thread seguro Desativar verificação de segurança de thread localmente ver abajo)
O arquivo de símbolos, se estiver habilitado, també contém o estado de thread de segurança para cada método:
Jà que são acessos "externos", as chamadas a objetos de interface de usuário, tais como formulários, assim como o Depurador não estão permitidas em threads preemptivos.
Os únicos acessos possíveis a interface de usuário de um thread preemptivo são:
Um número significativo de comandos 4D são thread seguro. Na documentação, a imagem na área de propriedade de comando indica que o comando for thread seguro. Pode obter a lista de comandos thread seguro no manual Referência da linguagem.
Também pode utilizar Command name que pode devolver a propriedade thread seguro para cada comando (ver abaixo).
Quando um método que utiliza um comando que pode ser chamado um disparador (trigger), o compilador 4D avalia a segurança de thread do disparador para comprovar a segurança de thread do método:
SAVE RECORD([Table_1]) //dispara em Table_1, se existir, deve ser thread seguro
Esta é a lista de comandos que se verificam no momento da compilação para a segurança de thread dos disparadores:
Se a tabela for passada dinamicamente, o compilador pode algumas vezes não encontrar que trigger avaliar. Estes são alguns exemplos de cada situação:
DEFAULT TABLE([Table_1])
SAVE RECORD
SAVE RECORD($ptrOnTable->)
SAVE RECORD(Table(myMethodThatReturnsATableNumber())->)
Neste caso, todos os triggers são selecionados. Se um comando thread inseguro for detectado em pelo menos um trigger, todo o grupo é rejeitado e o método é declaro thread inseguro.
Os métodos de captura de erros instalados pelo comando ON ERR CALL devem ser thread seguro se forprovável que sejam chamados desde um processo preemptivo. Com o fim de manejar este caso, o compilador verifica a propriedad de segurança de thread dos métodos de projeto de captura de erros passados ao comando ON ERR CALL durante a compilação e devolve os erros correspondentes se não cumprir com a execução preemptiva..
Lembre que esta comprovação só é possível quando o nome do método for passado como uma constante, e não for calculada, como se mostra abaixo:
ON ERR CALL("myErrMethod1") //será verificado pelo compilador
ON ERR CALL("myErrMethod"+String($vNum)) //não será verificado pelo compilador
Além disso, a partir de 4D v15 R5, se um método de projeto de captura de erros não pode ser chamado em tempo de execução (depois de um problema de segurança thread, ou por qualquer razão como "método não encontrado"), um novo erro é gerado -10532 "Não pode ser chamado o método de projeto de gestão de erros 'methodName'".
Um processo pode desreferenciar a um ponteiro para acessar ao valor de outra variável processo só se ambos processos são cooperativos, do contrário 4D gerará um erro. Em um processo preemptivo, se algum código 4D tentar desreferenciar um ponteiro a uma variável interprocesso, 4D gerará um erro.
Exemplo com os seguintes métodos:
Method1:
myVar:=42
$pid:=New process("Method2";0;"process name";->myVar)
Method2:
$value:=$1->
Se o processo que executa Method1 ou o processo que executa Method2 for preemptivo, a expressão "$value:=$1->" lançará um erro de execução.
O uso de tipo parâmetros DocRef (referência de documentos abertos, usados ou retornados por Open document, Create document, Append document, CLOSE DOCUMENT, RECEIVE PACKET, SEND PACKET) é limitado aos contextos abaixo:
Para saber mais sobre referências DocRef, veja DocRef: Número de referencia do documento
Em alguns casos, pode ser preferível a verificação "thread-safety" dos comandos não se aplica a algumas partes do código, como por exemplo, quando tiver comandos não thread seguro que sabe que nunca vão ser chamados.
Para fazer isto, deve rodear o código a excluir do comando thread seguro utilizando as diretivas específicas %T- y %T+ como comentários. O comentário //%T- desativa a verificação thread seguro e o comentário //%T+ a reativa:
// %T- para desabilitar a verificação thread seguro
// Coloque o código que contém os comandos que se excluirão da verificação thread seguro
$w:=Open window(10;10;100;100) //por exemplo
// %T+ para reativar novamente a verificação thread seguro para o resto de método
Lembre que o desenvolvedor 4D é responsável que o modo preemptivo do código seja compatível com as diretivas de ativação e de reativação. São gerados erros de tempo de execução se executar código thread não seguro em um thread preemptivo.
Produto: 4D
Tema: Processos
Criado por: 4D v15 R5
Manual de linguagem 4D ( 4D v19)
Manual de linguagem 4D ( 4D v19.1)
Manual de linguagem 4D ( 4D v19.4)
Manual de linguagem 4D ( 4D v19.5)
Manual de linguagem 4D ( 4D v19.6)
Manual de linguagem 4D ( 4D v19.7)
Manual de linguagem 4D ( 4D v19.8)