[Cascavel-pm] Controle de processo em perl

KLEBER payback em oi.com.br
Sexta Abril 6 06:38:42 PDT 2007


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 ).

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( )

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 ,

kleber








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


Olá Kleber,

On 2007/04/05, at 18:11, KLEBER wrote:

> Tomo a liberdade de enviar-lhe(s) este email cujo o assunto é PERL
> pois
> talvez você ou alguém que conheça  possa me ajudar.
> Estou escrevendo uma aplicação em perl  e preciso garantir que um
> determinado processo seja executado de forma única ( sem
> concorrência ).
>
> Pôr exemplo , uma função que atualiza uma tabela de agencia , ao ser
> executada  , todas as outras funções que acessam esta tabela deve
> esperar
> sua conclussão ( portanto deve-se formar uma fila de pedidos para
> atendimento ).
>
> Atualmente estou fazendo isto da seguinte maneira :
> #
> #      Permite executar um script por vez
> #
> denovo:
> if ( -e "c:\\payback\\contabil\\tabelas\\agencia\\cgiaform.nul" )
> { goto
> denovo; }
> sysopen( TASK15,
> "c:\\payback\\contabil\\tabelas\\agencia\\cgiaform.nul",
> O_WRONLY|O_EXCL|O_CREAT  ) or warn ( goto denovo );
> flock( TASK15, LOCK_EX ) or warn ( goto denovo );
> ---------------------------------
> Instruções diversas em perl  5.8
> --------------------------------
> flock( TASK15, LOCK_UN );
> close( TASK15 );
> unlink( "c:\\payback\\contabil\\tabelas\\agencia\\cgiaform.nul" );
> exit;
>

Uma maneira primitiva de fazer a mesma coisa, utilizando arquivos
como lock.

<code>
use File::Slurp;

PROCESS:
{
     if ( -e $LOCK_FILE ) {

         sleep 1;
         redo PROCESS;
     }

     write_file($LOCK_FILE, $$);

     do_whatever_you_want();

     unlink $LOCK_FILE;
}
</code>

Agora com flock:

<code>
# importa constantes para flock e seek
use Fcntl qw(:flock :seek);

# abre arquivo.
open my $fh, "<", $filename or die $!;

# aciona lock no filehandle. vai esperar aqui até outra instância do
programa liberar o arquivo.
flock($fh, LOCK_EX);

# move cursor para o final do arquivo
seek($fh, 0, SEEK_END);

# imprime algo
print $fh "Some text!\n";

# desbloqueia o filehandle
flock($fh, LOCK_UN);

# fecha o arquivo
close $fh or warn $!;
</code>

Lembre-se que flock() atua em filehandles. Lembre-se também que flock
() funciona apenas com outros programas que utilizam flock(), isto é,
se um outro programa for interagir com este arquivo e não utilizar
flock(), provavelmente irá ocasionar problemas.

Alguns outros pontos a considerar:

- Labels são, no senso comum, nomeados com letras MAIUSCULAS pois
ajudam a distinguir de funções;
- Utilize File::Spec para tratar com caminhos de arquivos;
- Apesar de utilizarmos labels, 'goto's são feios :-P Utilize escopos
para isso, como no exemplo que transcrevi;
- Não é necessário utilizar as rotinas sys* a menos que você saiba o
que está fazendo :-);
- Utilize scalars para armazenar a referência de arquivos abertos com
open, ao invés de barewords.

Acho que é só, e espero que ajude.
--
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