[Cascavel-pm] Controle de processo em perl

KLEBER payback em oi.com.br
Sexta Abril 6 09:34:36 PDT 2007


Ok Igor ,

Mais uma vez agradeço sua atenção.
Vou tentar descrever meu problema.
Eu desenvolvo sistema e estou trabalhando com 3 linguagens:
                            Cobol , javascript , perl.

Basicamente estas linguagens atuam da seguinte maneira :

          Javascript - Realiza validação dos dados ( formulario ) na máquina 
do
                            cliente.
          Perl - Recebe os dados do formulario do cliente , grava em um 
arquivo
                   texto para entrada de dados no cobol , executa um 
programa
                    cobol através do comando system e envia a resposta ao 
cliente.
         Cobol - Lê arquivo de entrada de dados , realiza manutenção na base
                     de dados e gera um arquivo html sobre o status do
                      processamento.
                     A resposta enviada pelo perl ao cliente está neste 
arquivo html.

Ao realizar alguns testes com uso concorrente ( duas pessoas acessando a
mesma rotina perl ) , verifiquei que o arquivo html gerado pelo cobol  do 
usuário A estava sendo direcionado para usuario B.
Resolvi este problema criando um arquivo nulo e testando sua existência
para execução de um processo perl.
Entretanto , tenho consiência de que não é a melhor solução pois , caso
exista algum problema na rotina perl e o arquivo de controle não é eliminado 
,
todas as solicitações vão ficar dependurada.

Pesquisando este assunto , verifiquei a possibilidade de utilizar a 
alternativa
de controle de processo ( wait ).
O objetivo é executar uma rotina em perl sem uso concorrente ou seja ,
enquanto ela estiver sendo executada , todas as solicitações de execução 
desta rotina devem aguadar.

Vou dar um exemplo prático deste problema :

O sistema que estou escrevendo realiza autenticação do usuário.
Ou seja , o usuário informa de seu codigo de acesso e senha , envia os dados 
ao perl que grava em um arquivo texto para passagem ao cobol.
O cobol verifica se os dados estão corretos e grava arquivo de autorização 
de acesso ( html ) que contém informações tais como : quais sistemas o 
usuário pode acessar , qual o nivel de autorização deste usuário ( acessa 
todas as funções ou modulos do sistema ) , qual o status do usuário ( 
privilegiado , normal , etc ).
Este arquivo de autorização de acesso pertence ao usuário A e não pode
ser direcionado para o usuário B.

Por isso preciso garantir que , enquanto um processo perl  esteja sendo 
executado , todos os demais precisam aguardar sua conclussão.

Espero ter descrito com mais clareza minha necessidade.

Um abraço ,

kleber




----- Original Message ----- 
From: "Igor Sutton Lopes" <igor.sutton em gmail.com>
To: "Cascavel Perl Mongers" <cascavel-pm em pm.org>
Sent: Friday, April 06, 2007 12:23 PM
Subject: Re: [Cascavel-pm] Controle de processo em perl


Olá Kleber,

On 2007/04/06, at 14:38, KLEBER wrote:

> Olá  Igor ,
>
> Agradeço sua gentileza em me responder.
>
> Entendi suas considerações e devo te dizer que não sou um especialista
> em perl ( conheço com alguma profundidade cobol )
> O pouco que conheço , aprendi lendo o livro Perl como programar
> ( deitel ).
> Sobre o tema controle de processo , estava imaginando controlá-lo ,
> não
> através de arquivo , mas pelo PID.
> ( me desculpe se estou falando bobagem ).

Pelo que me recordo da sua mensagem inicial, você queria utilizar um
controle de processos relacionado ao filehandle, isto é, não permitir
que dois processos concorrentes modifiquem o mesmo arquivo, ao mesmo
tempo. Isto você consegue com flock(), conforme você o fez e eu
enviei uma abordagem mais perlish.

Agora, se você quer controlar processos concorrentes através de fork
() e wait(), é um pouco diferente.

>
> De acordo com o livro mencionado , o pid está na variável  $PROCESS_ID
> e existe uma função chamada WAIT( )  que aguarda o término de um
> processo.
> A minha necessidade seria resolvida formulando a seguinte indagação :
>
> ENQUANTO $PROCESS_ID  ESTIVER  ATIVO WAIT( )

A pergunta que fica é: você que está iniciando estes processos
concorrentes, ou o sistema operacional?

Ah, em relação à variável $PROCESS_ID, você precisa utilizar 'use
English;' no início do seu programa (perldoc English para maiores
informações).

>
> Não sei se é possível este tipo de contole em perl e , se for , como
> codificá-lo.
> 
> Nota - Consta as seguintes informações neste livro :
>             a) Na variável especial  $PID   consta o numero do
> processo do
>                 próprio programa.
>             b) Se quiser esperar que termine a execução de processo
> específico ,
>                 você pode usar a função WAITPID , que recebe um
> processo
>                 como primeiro argumento.Ela espera que aquele processo
> termine
>                 e então devolve o pid daquele processo.
>                 Se não houver nenhum filho para aquele pid ou se já
> estiver
> morto ,
>                 a função WAITPID devolve -1.
>                 O estado de saida do processo filho é armazenada na
> variável
>                 especial  $?.
>             c) Exemplo de controle de processo no livro ( dois
> processos ) :
>                 my ( $pid, $pid2 );
>                 s| = 1;
>                 if (  ( $pid = fork()  ) && ( $pid2 = fork() ) ) {
>                       print ( "Preciso esperar meus filhos.\n" );
>                       my $straggler = wait();
>                      print ( "Finalmente $straggler terminou.Agora
> eu posso
> ir.\n" );
>                 }
>                 elsif ( $pid && defined(  $pid2 ) ) {
>                         sleep( 2 );
>                         print( "Filho 2 : O meu tambem....\n" );
>                         sleep( 4 );
>                         exit ();
>               }
>                elsif ( defined( $pid ) ) {
>                         sleep( 1 );
>                        print( "Filho 1 : Meu pai tem paciencia......
> \n" );
>                        sleep( 2 );
>               }
>               else {
>                   die(  "Problemas com fork " );
>               }
>
>              Acredito que neste programa exemplo esteja a solução
> do meu
>              problema , entretanto , pôr não dominar o perl , não
> sinto
>              segurança para interpletá-lo.
>
> Mais uma vez , agradeço a sua atenção ,

Certo, vamos lá com um exemplo de fork():

<code>
use strict;
use warnings;

use POSIX qw(:sys_wait_h);

sub message {
     print "[$$] ", @_, $/;
}

sub REAPER {
     while ( ( my $child = waitpid( -1, WNOHANG ) ) > 0 ) {
         message( "filho $child morreu", $/ );
     }
     $SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;

my $pid = fork();
unless ( defined $pid ) {
     die "problemas ao executar fork(): $!";
}

if ( $pid > 0 ) {    # estamos no processo pai
     message( "iniciei o processo $pid", $/ );
     sleep 5;
     message( "pai esta saindo", $/ );
exit;
}
else {               # estamos no processo filho
     message( "eu sou o filho!", $/ );
     exit;
}

</code>

Para maiores informações:

perldoc perlipc
perldoc POSIX
perldoc -f fork

A propósito: o que é que você quer fazer, afinal? Descreva-nos o seu
problema, assim fica mais fácil de ajudá-lo :-)

Abraço!

--
Igor Sutton
igor.sutton em gmail.com






--------------------------------------------------------------------------------


_______________________________________________
Cascavel-pm mailing list
Cascavel-pm em pm.org
http://mail.pm.org/mailman/listinfo/cascavel-pm 



Mais detalhes sobre a lista de discussão Cascavel-pm