4D v16.3

Processos 4D Preemptivos

Página Inicial

 
4D v16.3
Processos 4D Preemptivos

Processos 4D Preemptivos  


 

 

4D Developer Edition de 64 bits para Windows (a partir de 4D V16 R2) e OS X vem com uma nova funcionalidade de grande alcance que lhe permite escrever e utilizar código 4D preemptivo. Graças a esta nova funcionalidade, seus aplicativos 4D compilados poderão aproveitar ao  máximo os computadores de vários núcleos de modo que sua execução será mais rápida e pode suportar mais usuários conectados.

Quando for executado em modo preemptivo, um processo estará dedicado a uma CPU. A gestão de processos então é delegada ao sistema, que pode adjudicar por separado cada CPU em uma máquina multi-núcleo.

Quando for executado em modo cooperativo (o único modo disponível em 4D até 4D v15 R5), todos os processos serão gestionados pelo thread da aplicação pai e compartem a mesma CPU, mesmo em uma máquina multi-núcleo.

Como resultado, no modo apropriativo, o rendimento global da aplicação é incrementado, especialmente em máquinas multi-núcleo, já que múltiplos processos (threads ou fios) podem ser executados simultaneamente. Entretanto, os ganhos reais dependem das operações executadas.

Por outro lado, já  que no modo apropriativo cada fio é independente dos demais e não é gestionado diretamente pela aplicação, limitações específicas se aplicam aos métodos que queira que sejam compatíveis com o modo apropriativo. Além disso, a execução apropriativa está disponível só em alguns contextos específicos.

O uso do modo preemptivo está disponível nos seguintes contextos de execução:

Execução Preemptiva
4D ServerX
4D remote-
4D single-userX
Modo CompiladoX
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.

Nota: Pode executar um processo em modo preemptivo a partir de um 4D remoto ao iniciar um procedimento armazenado no servidor com a linguagem, por exemplo usando Execute on server.

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:

  • Comandos 4D:  thread seguro é uma propriedade interna. Na referência da linguagem, os comandos thread seguro se identificam pela imagem . Grande parte dos comandos 4D podem ser executados em modo apropriativo.
  • Métodos de projeto: as condições para segurança de thread se listam no parágrafo Como escrever um código thread seguro.

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:

  • Pode ser executado em um processo preemptivo: ao selecionar esta opção, declara que o método é capaz de ser executado em um processo preemptivo e portanto deve ser executado em modo preemptivo quando for possível. A propriedade "preemptiva" do método é ativada.
    Quando for selecionada esta opção, o compilador 4D verificará que o método esteja realmente ativo e devolverá erro se não for o caso, por exemplo, se direta ou indiretamente chamar a comandos ou métodos que não  podem ser executados em modo preemptivo (toda a cadeia de chamadas se analisa, mas só os erros são comunicados ao primeiro subnível). Depois, pode editar o método para que seja thread seguro ou selecionar outra opção.
    Se a elegibilidade do método ao modo preemptivo for aprovada, se etiqueta "thread-seguro" internamente e se executará no modo preemptivo sempre que se cumpram as condições requeridas. Esta propriedade define sua elegibilidade para o modo preemptivo, mas não garante que o método realmente possa ser executado em modo preemptivo, já que este modo de execução requer um contexto específico (ver Quando um processo é iniciado de forma preemptiva?).
  • Não pode ser executado em um processo preemptivo: selecionando esta opção, se declara que o método não deve ser executado em modo preemptivo, e portanto sempre se deve executar em modo cooperativo, da mesma forma que nas versões anteriores de 4D. A propriedad "preemptiva" do método se ativa.
    Quando for selecionada esta opção, o compilador 4D não verificará a capacidade do método para ser executado de forma preemptiva; se marcar de forma automática "thread-inseguro" internamente (mesmo se for  teoricamente compatível). Quando for chamado em execução, este método "contamina" qualquer outro método na mesma thread, o que obriga a este thread que seja executado em modo cooperativo, mesmo se os outros métodos forem thread seguro.
  • Indiferente (pré-determinado): Ao selecionar esta opção, declara que não deseja manejar a propriedad preventiva para o método. A propriedad "preventiva" do método se estabelece em "indiferente".  Quando for selecionada esta opção, o compilador 4D avaliará a capacidade preventiva do método e etiquetará internamente como "thread-seguro" ou "thread-insegura". Não se devolve nenhum erro relacionado com a execução preferente. Se for avaliado o  método multi-thread, em tempo de execução que não impedirá a execução de thread preventiva quando for chamado em um contexto preventivo. Pelo contrário, se o método for avaliado como "thread-inseguro", em tempo de execução, se evitará qualquer execução de thread preventiva quando for chamada.

   Lembre que com esta opção, qualquer que seja a avaliação interna thread de segurança, sempre se executará o método no modo cooperativo quando for chamado diretamente por 4D como o primeiro método de matriz (por exemplo através da [id #cmd = "317" /] de comandos). Se etiquetado como "thread-safe" internamente, só será levado em consideração quando for chamado  desde outros métodos dentro de uma cadeia de chamadas.

 

Nota: Um método de componente declarado como "Shared with components and host databases" também deve ser declarado "capable" para ser executado em uma thread preemptiva pelo banco de dados host.

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 valo rde "indifferent", "capable", ou "incapable".

A tabela abaixo resume os efeitos das opções de declaração do modo preemptivo

OpçãoValor de propriedade Preemptiva (interpretado)Ação CompiladorEtiqueta Interna (compilado)Modo de Execução se chain chamada for thread-seguro

Pode ser executado em processos preemptivos

capazCheca capacidade e retorna erros se incapazthread-seguroPreemptivo
Não pode ser executado em processos preemptivosincapazNenhuma avaliaçãothread-inseguroCooperativo
IndifferentindiferenteAvaliação mas erros não são retornadosthread-sesguro ou thread-inseguroSe 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:

  • Se o método processo for thread seguro (validado durante a compilação), o processo é executado em um thread apropriativo.
  • Se o método processo for thread inseguro, o processo é executado em um thread cooperativo.
  • Se a propriedade apropiativa do método de processo era "indiferente", por compatibilidade o processo é executado em um thread cooperativo (mesmo se o método for realmente capaz). Note entretanto que esta funcionalidade de compatibilidade for aplicada só quando for utilizado o método como método de processo: um método declarado "indiferente", mas internamente etiquetado "thread seguro" pelo compilador pode ser chamado de forma apropriativa por outro método (ver abaixo).

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

  //CallDial project method
 MyDialog

  //CallComp project method
 MyCom(10)

A tabela abaixo ilustra estas diversas situações:

Declaração e cadeia de chamadasCompilaçãoSegurança de thread resultanteComentárioExecução
OKMétodo A é o método pai, declarado "capaz" de uso apropriativo; já que o método B é internamente thread seguro, o método A é thread seguro e o processo é apropriativoApropriativo
ErrorO método C é o método pai, declarado "capaz"; entretanto, já que o método E está internamente como thread inseguro, contamina a cadeia de chamadas. A compilação falha devido a um conflito entre a declaração de método C e a capacidade realA solução é modificar o método E para que seja thread seguro (suponndo que o método D seja thread seguro), de modo que a execução seja apropriativa, ou mudar a declaração de propriedade do método C  a cooperativo
OKComo o método F se declara "incapaz" de uso apropriativo, a compilação é internamente thread inseguro, a execução sempre será cooperativa, qualquer que seja o estado de método GCooperativo
OKDesde que o método H seja o método pai (a propriedad era "indiferente") , o processo é cooperativo. A compilação é exitosa, mesmo  se o método for declarado "capaz"Cooperativo
OKo método J é o método pai (propriedade "indiferente"), então o proceso é cooperativo, mesmo se toda a cadeia for thread seguroCooperativo

Nota: o comando PROCESS PROPERTIES lhe permite saber se um processo é executado em modo apropriativo ou cooperativo.

4D lhe oferece novas funcionalidades para identificar a execução cooperativa ou apropriativa para processos:

  • O comando PROCESS PROPERTIES lhe permite averiguar se um proceso é executado em modo apropriativo ou cooperativo.
  • O Explorador de execução e a janela de administração de 4D Server mostram novos ícones específicos para os processos apropriativos (assim como também novos processos worker):
    Tipo de processoIcone
    Processo armazenado apropriativo
    Processo worker apropriativo
    Processo worker cooperativo

Para ser thread seguro, um método deve respeitar as seguintes regras:

  • deve ter a propriedade "Pode ser executado em processos preemptivos" ou "Indiferente"
  • não chama a um comando 4D que seja thread inseguro.
  • não chama a outro método de projeto que seja thread inseguro
  • não chama a um plug-in
  • não utiliza blocos de código begin sql/end sql
  • não utiliza nenhuma variável interprocessos(*)
  • não chama a objetos de interface(**) (há exceções, ver abaixo).

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.

(*) Um novo tipo de processo chamado processo Worker, permite o intercâmbio de dados entre todos os processos, incluindo os processos preemptivos. Para saber mais, consulte Sobre Workers.
(**) O novo comando CALL FORM 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:

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:

  • diálogo de erro padrão. O diálogo se mostra no processo modo de usuário (em 4D monousuario) ou o processo de interface de usuário do servidor (4D Server). O botão Rastreio está desabilitado.
  • indicadores de progresso padrão
  • Diálogos ALERT, REQUEST e CONFIRM. O diálogo se mostra no processo modo usuário (em 4D monousuario) ou o processo de interface de usuário do servidor (4D Server).
    Lembre que se 4D Server for lançado como um serviço em Windows sem intervenção de usuário permitido, não serão mostrados os diálogos.

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:

  • SAVE RECORD
  • SAVE RELATED ONE
  • DELETE RECORD
  • DELETE SELECTION
  • ARRAY TO SELECTION
  • JSON TO SELECTION
  • APPLY TO SELECTION
  • IMPORT DATA
  • IMPORT DIF
  • IMPORT ODBC
  • IMPORT SYLK
  • IMPORT TEXT

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:

  • Quando chamado para um processo preemtivo, uma referência DocRef é usável apenas a partir daquele processo preemptivo.
  • Quando chamado de um processo cooperativo, uma referência DocRef é usável a partir de qualquer outro processo cooperativo.

Para saber mais sobre referências DocRef, veja  DocRef: Número de referencia do documento



Ver também 

Command name
Usar processos Web preemptivos

 
PROPRIEDADES 

Produto: 4D
Tema: Processos

 
HISTÓRIA 

Criado por: 4D v15 R5

 
ARTICLE USAGE

Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)