Introducción

Besides addressing a process by using its pid, there are also BIFs for registering a process under a name. The name must be an atom and is automatically unregistered if the process terminates:

register(Name, Pid) Associates the name Name, an atom, with the process Pid.
registered() Returns a list of names which have been registered using register/2.
whereis(Name) Returns the pid registered under Name, or undefined if the name is not registered.

pp2@nereida:~/Lerlang$ cat -n area_server0.erl
     1  -module(area_server0).
     2  -export([loop/0]).
     3  %% ~~~~~~
     4
     5  loop() ->
     6      receive
     7        {rectangle, Width, Ht} ->
     8          io:format("Area of rectangle is ~p~n", [Width*Ht]),
     9          loop();
    10        {circle, R} ->
    11          io:format("Area of circle is ~p~n", [3.14159*R*R]),
    12          loop();
    13        Other ->
    14          io:format("I don't know what the area of a ~p is ~n", [Other]),
    15          loop()
    16      end.

3> c(area_server0).
{ok,area_server0}

4> Pid = spawn(fun area_server0:loop/0 end).
* 2: syntax error before: 'end'
4> Pid = spawn(fun area_server0:loop/0).
<0.45.0>
5> register(area, Pid).
true
6> area! { rectangle, 4, 5}
6> .
Area of rectangle is 20
{rectangle,4,5}

Un Reloj

pp2@nereida:~/Lerlang$ erl
Erlang (BEAM) emulator version 5.6.5 [source] [64-bit] [smp:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.6.5  (abort with ^G)
1> c(clock).
{ok,clock}
2> clock:start(5000, fun() -> io:format("TICK ~p~n", [erlang:now()) end).
* 1: syntax error before: ')'
2> clock:start(5000, fun() -> io:format("TICK ~p~n", [erlang:now()]) end).
true
TICK {1259,174993,316298}
TICK {1259,174998,320447}
TICK {1259,175003,325772}
TICK {1259,175008,330987}
TICK {1259,175013,332715}
3> clock:stop().
stop
4>
pp2@nereida:~/Lerlang$ cat -n clock.erl
     1  -module(clock).
     2  -export([start/2, stop/0]).
     3
     4  start(Time, Fun) ->
     5      register(clock, spawn(fun() -> tick(Time, Fun) end))
     6  .
     7
     8  stop() -> clock! stop.
     9
    10  tick(Time, Fun) ->
    11      receive
    12          stop -> void
    13      after Time -> Fun(), tick(Time, Fun)
    14      end
    15  .



Subsecciones
Casiano Rodríguez León
2010-03-22
tex2html10" HREF="http://www.ull.es/">ullpcgull
Sig: Apéndice Sup: Erlang Ant: Introducción
Casiano Rodríguez León
2010-05-05
LT="next" SRC="next.png"> up previous contents index PP2PP2 moodlepsmodulosperlmonksperldocperlcriticpbpgoogle code project hostingintro a PerlModern Perlblogsgoogleetsiiullpcgull
Sig: El Sistema de FLAGS Sup: Las Interioridades de Perl Ant: Argumentos de Salida en
Casiano Rodríguez León
2011-03-18
or Example.xs (see perlxs manual) !11 cc -c -I. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing ! -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 ! -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC "-I/usr/lib/perl/5.8/CORE" ! Example.c !12 Running Mkbootstrap for Example () !13 chmod 644 Example.bs !14 rm -f blib/arch/auto/Example/Example.so !15 cc -shared -L/usr/local/lib Example.o -o blib/arch/auto/Example/Example.so \ 16 \ 17 !18 chmod 755 blib/arch/auto/Example/Example.so !19 cp Example.bs blib/arch/auto/Example/Example.bs !20 chmod 644 blib/arch/auto/Example/Example.bs 21 Manifying blib/man3/Example.3pm

Expliquemos en mas detalle la secuencia anterior:

  1. Se crea el Makefile (líneas 1-4) a partir de Makefile.PL:
    lhp@nereida:~/Lperl/src/XSUB/Example$ cat -n Makefile.PL
     1  use 5.008008;
     2  use ExtUtils::MakeMaker;
     3  # See lib/ExtUtils/MakeMaker.pm for details of how to influence
     4  # the contents of the Makefile that is written.
     5  WriteMakefile(
     6      NAME              => 'Example',
     7      VERSION_FROM      => 'lib/Example.pm', # finds $VERSION
     8      PREREQ_PM         => {}, # e.g., Module::Name => 1.1
     9      ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
    10        (ABSTRACT_FROM  => 'lib/Example.pm', # retrieve abstract from module
    11         AUTHOR         => 'Lenguajes y Herramientas de Programacion') : ()),
    12      LIBS              => [''], # e.g., '-lm'
    13      DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
    14      INC               => '-I.', # e.g., '-I. -I/usr/include/other'
    15          # Un-comment this if you add C files to link with later:
    16      # OBJECT            => '$(O_FILES)', # link all the C files too
    17  );
    
    La ejecución de Makefile.PL detecta la presencia de ficheros .xs en el directorio y adapta el Makefile para que dichos ficheros sean procesados.
  2. Se copian los ficheros al directorio de construcción blib/lib/ (líneas 7-8). El nombre blib viene de Build Library.
  3. Se ejecuta el traductor de XS a C xsubpp (línea 9). El compilador usa unos ficheros de información denominados typemap para determinar la correspondencia entre los tipos de C y los de Perl. En vez de producir directamente un fichero con extensión .c la salida se almacena en un fichero temporal Example.xsc y luego se renombra como Example.c. Ello se hace para evitar que ficheros en proceso de formación puedan ser erróneamente tomados por código C válido.
  4. El warning de la línea 10 puede ser ignorado. En XS es posible especificar un prototipo Perl para determinar la forma en la que ocurre la llamada a la XSUB (vea un ejemplo en la sección 17.11). El mensaje de advertencia puede desactivarse usando la directiva PROTOTYPES: DISABLE en el fichero XS justo después de la declaración MODULE:
    lhp@nereida:~/Lperl/src/XSUB/Example$ cat -n Example.xs
         1  #include "EXTERN.h"
         2  #include "perl.h"
         3  #include "XSUB.h"
         4
         5  #include "ppport.h"
         6
        ..  .................................................
        20  MODULE = Example                PACKAGE = Example
        21  PROTOTYPES: DISABLE
        22
        23  double
        24  computepi(id, N, np)
        25  int id
        26  int N
        27  int np
    
  5. Se compila el fichero Example.c generado por xsubpp (línea 11).
    cc -c  -I. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN \
      -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE \
      -D_FILE_OFFSET_BITS=64 -O2-DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" \
      -fPIC "-I/usr/lib/perl/5.8/CORE" Example.c
    
    El compilador y las opciones del compilador usadas son las mismas que se emplearon para construir la instalación actual del intérprete Perl. Los valores con los que la versión usada de Perl fue compilada pueden obtenerse por medio del módulo Config . Por ejemplo:
    lhp@nereida:~/Lperl/src/XSUB$  perl -MConfig -e 'print Config::myconfig()'
    Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
      Platform:
        osname=linux, osvers=2.6.15.4, archname=i486-linux-gnu-thread-multi
        uname='linux ninsei 2.6.15.4 #1 smp preempt mon feb 20 09:48:53 pst 2006\
                                                 i686 gnulinux '
        config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
        -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu
        -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8
        -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr
        -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
        -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8
        -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1
        -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
        -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl
        -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm
        -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
        hint=recommended, useposix=true, d_sigaction=define
        usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
        useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
        use64bitint=undef use64bitall=undef uselongdouble=undef
        usemymalloc=n, bincompat5005=undef
    ! Compiler:
    !   cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
    !   -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include
    !   -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    !   optimize='-O2',
        cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN 
                 -fno-strict-aliasing -pipe -I/usr/local/include'
        ccversion='', gccversion='4.0.3 (Debian 4.0.3-1)', gccosandvers=''
        intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
        d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
        ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
        alignbytes=4, prototype=define
      Linker and Libraries:
        ld='cc', ldflags =' -L/usr/local/lib'
        libpth=/usr/local/lib /lib /usr/lib
        libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
        perllibs=-ldl -lm -lpthread -lc -lcrypt
        libc=/lib/libc-2.3.6.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
        gnulibc_version='2.3.6'
      Dynamic Linking:
        dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
        cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'
    
  6. A continuación se procede a la construcción de la librería dinámica. El proceso depende de la plataforma y la forma de hacerlo viene de nuevo dirigida por el módulo Config. Observe que la librería se deja en el directorio blib/arch/auto/Example/ (línea 18).
    !13 chmod 644 Example.bs
    !14 rm -f blib/arch/auto/Example/Example.so
    !15 cc  -shared -L/usr/local/lib Example.o  -o blib/arch/auto/Example/Example.so    \
     16                 \
     17 
    !18 chmod 755 blib/arch/auto/Example/Example.so
    !19 cp Example.bs blib/arch/auto/Example/Example.bs
    !20 chmod 644 blib/arch/auto/Example/Example.bs
     21 Manifying blib/man3/Example.3pm
    

Para probar el módulo escribimos un programa de prueba:

lhp@nereida:~/Lperl/src/XSUB/Example$ cat -n useexample.pl
 1  #!/usr/bin/perl -w
 2  use blib; # Para que encuentre el módulo
 3  use strict;
 4  use Example;
 5
 6  my $n = shift || 1000;
 7  my $x = 0;
 8
 9  $x += Example::computepi(0,$n,4) for 0..3;
10  print "$x\n";
lhp@nereida:~/Lperl/src/XSUB/Example$ time ./useexample.pl 1000
3.14459174129814

real    0m0.032s
user    0m0.020s
sys     0m0.010s
lhp@nereida:~/Lperl/src/XSUB/Example$ time ./useexample.pl 10000000
3.14159295358978

real    0m0.359s
user    0m0.360s
sys     0m0.000s



Subsecciones
Casiano Rodríguez León
2011-04-11