> -----Original Message----- > From: Enric Roca [mailto:[EMAIL PROTECTED]] > Sent: Monday, January 27, 2003 4:09 PM > To: NYIMI Jose (BMB); Beginners Perl > Subject: RE: Concurrency problem > > > José, > > Thanks for the info, but forget that I'm using pipes. I need > that the perl script, when is executed, first detect if it is > already executing and if it is wait for some miliseconds. I'm
Although, I never got the opportinuity to use it, One way is to use Proc::ProcessTable module http://search.cpan.org/author/DURIST/Proc-ProcessTable-0.38/ And write something like: (not tested !) #!/usr/bin/perl -w use strict; use Proc::ProcessTable; use File::Basename; my $is_running=&a_check_subroutine(); sleep (60) if $is_running;#sleep 60 seconds sub a_check_subroutine{ my $script=quotemeta File::Basename::basename($0); my $t = new Proc::ProcessTable; foreach my $p (@{$t->table}){ return 1 if $p->cmndline =~ /$script/ ; } return 0; } __END__ HTH, José. > new in Perl so I don't know how to get this, but if this was > possible I think that it would solve my problem. > > Regards, > > Enric > > > ----- Mensaje original ----- > De: "NYIMI Jose (BMB)" <[EMAIL PROTECTED]> > Para: "Enric Roca" <[EMAIL PROTECTED]>; "Beginners > Perl" <[EMAIL PROTECTED]> > Enviado: lunes 27 de enero de 2003 15:09 > Asunto: RE: Concurrency problem > > > Sorry :) but your script seems not doing what you explained > above. I have the impression that your problem is not related > to a concurrency problem. Could you send a more detailed code, please? > > José. > > Anyway, here some reads from Perl Cookbook : > > > 16.11. Making a Process Look Like a File with Named Pipes > Problem You want a process to intercept all access to a file. > For instance, you want to make your ~/.plan file a program > that returns a random quote. > > Solution > Use named pipes. First create one, probably from your shell: > > % mkfifo /path/to/named.pipe > Here's a reader for it: > > open(FIFO, "< /path/to/named.pipe") or die $!; > while (<FIFO>) { > print "Got: $_"; > } > close(FIFO); > Here's a writer for it: > > open(FIFO, "> /path/to/named.pipe") or die $!; > print FIFO "Smoke this.\n"; > close(FIFO); > Discussion > A named pipe, or FIFO as they are also known, is a special > file that acts as a buffer to connect processes on the same > machine. Ordinary pipes also allow processes to communicate, > but those processes must have inherited the filehandles from > their parents. To use a named pipe, a process need know only > the named pipe's filename. In most cases, processes don't > even need to be aware that they're reading from a FIFO. > > Named pipes can be read from and written to just as though > they were ordinary files (unlike Unix-domain sockets as > discussed in Chapter 17, Sockets). Data written into the FIFO > is buffered up by the operating system, then read back in the > order it was written in. Because a FIFO acts as a buffer to > connect processes, opening one for reading will block until > another process opens it for writing, and vice versa. If you > open for read and write using the +< mode to open, you won't > block (on most systems) because your process could be both > reader and writer. > > Let's examine how to use a named pipe so people will get a > different file each time they finger you. To create a named > pipe, use mkfifo or mknod to create a named pipe called .plan > in your home directory: > > % mkfifo ~/.plan # isn't this everywhere yet? > % mknod ~/.plan p # in case you don't have mkfifo > On some systems, you must use mknod (8). The location and > names of these programs aren't uniform or necessarily > obvious, so consult your system documentation to find out > where these programs are. > > The next step is to create a program to feed data to the > programs that read from your ~/.plan file. We'll just print > the date and time, as shown in Example 16.9. > > Example 16.9: dateplan > #!/usr/bin/perl -w > # dateplan - place current date and time in .plan file > while (1) { > open(FIFO, "> $ENV{HOME}/.plan") > or die "Couldn't open $ENV{HOME}/.plan for writing: $!\n"; > print FIFO "The current time is ", scalar(localtime), "\n"; > close FIFO; > sleep 1; > } > Unfortunately, this won't always work, because some finger > programs and their attendant daemons check the size of the > .plan file before trying to read it. Because named pipes > appear as special files of zero size on the filesystem, such > clients and servers will not try to open or read from our > named pipe, and the trick will fail. > > In our .plan example, the writer was a daemon. It's not > uncommon for readers to be daemons as well. Take, for > instance, the use of a named pipe to centralize logging from > many processes. The log server reads log messages from the > named pipe and can send them to a database or file. Clients > write their messages to the named pipe. This removes the > distribution logic from the clients, making changes to > message distribution easy to implement. > > Example 16.10 is a simple program to read two-line messages > where the first line is the name of the service and the > second line is the message being logged. All messages from > httpd are ignored, while all messages from login are saved to > /var/log/login. > > Example 16.10: fifolog > #!/usr/bin/perl -w > # fifolog - read and record log msgs from fifo > > use IO::File; > > $SIG{ALRM} = sub { close(FIFO) }; # move on to the next > queued process > > while (1) { > alarm(0); # turn off alarm for blocking open > open(FIFO, "< /tmp/log") or die "Can't open > /tmp/log : $!\n"; > alarm(1); # you have 1 second to log > > $service = <FIFO>; > next unless defined $service; # interrupted or nothing logged > chomp $service; > > $message = <FIFO>; > next unless defined $message; # interrupted or nothing logged > chomp $message; > > alarm(0); # turn off alarms for > message processing > > if ($service eq "http") { > # ignoring > } elsif ($service eq "login") { > # log to /var/log/login > if ( open(LOG, ">> /tmp/login") ) { > print LOG scalar(localtime), " $service $message\n"; > close(LOG); > } else { > warn "Couldn't log $service $message to > /var/log/login : $!\n"; > } > } > } > This program is more complicated than the .plan program for > several reasons. First and foremost, we don't want our > logging server to block would-be writers for long. It's easy > to imagine a situation where an attacker or misbehaving > writer opens the named pipe for writing, but doesn't send a > complete message. To prevent this, we use alarm and SIGALRM > to signal us if we get stuck reading. > > Only two exceptional conditions can happen when using named > pipes: a writer can have its reader disappear, or vice versa. > If a process is reading from a named pipe and the writer > closes its end, the reading process will get an end of file > (<> returns undef). If the reader closes the connection, > though, the writer will get a SIGPIPE when it next tries to > write there. If you disregard broken pipe signals with > $SIG{PIPE} = 'IGNORE', your print will return a false value > and $! will be set to EPIPE: > > use POSIX qw(:errno_h); > > $SIG{PIPE} = 'IGNORE'; > # ... > $status = print FIFO "Are you there?\n"; > if (!$status && $! == EPIPE) { > warn "My reader has forsaken me!\n"; > next; > } > You may be asking "If I have 100 processes all trying > simultaneously to write to this server, how can I be sure > that I'll get 100 separate entries and not a jumbled mishmash > with characters or lines from different processes?" That's a > good question. The POSIX standard says that writes of less > than PIPE_BUF bytes in size will be delivered atomically, > i.e. not jumbled. You can get the PIPE_BUF constant from POSIX: > > use POSIX; > print _POSIX_PIPE_BUF, "\n"; > Fortunately, the POSIX standard also requires PIPE_BUF to be > at least 512 bytes. This means that all we have to do is > ensure that our clients don't try to log more than 512 bytes > at a time. > > What if you want to log more than 512 bytes at a time? Then > you split each large message into several smaller (fewer than > 512 bytes) messages, preface each with the unique client > identifier (process ID, say) and have the server reassemble > them. This is similar to the processing involved in TCP/IP > message fragmentation and reassembly. > > Because a single named pipe doesn't allow bidirectional > access between writer and reader, authentication and similar > ways of preventing forged messages are hard to do (if not > impossible). Rather than struggle to force such things on top > of a model that doesn't accommodate them, you are better off > using the filesystem's access control to restrict access to > the file through the owner and group permissions on the named pipe. > > See Also > mkfifo (8) or mknod (8) (if you have them); Recipe 17.6 > > > > -----Original Message----- > > From: Enric Roca [mailto:[EMAIL PROTECTED]] > > Sent: Monday, January 27, 2003 12:21 PM > > To: Beginners Perl > > Subject: Concurrency problem > > > > > > Hello, > > > > We are using Apache 1.3.26, Perl 5.5.3 and perl-cgi scripting to > > communicate to applications with XML. App1 calls the cgi > script that > > is placed in the other machine. The script reads the XML > message and > > pass it to pipe1. This message is processed by App2 and a response > > message is returned to pipe2 and sent to App1. > > > > The process works fine, but we have detected an issue when > more that > > one XML message is sent at the same time. The first message that > > arrives is well processed but the second message is lost. > > > > Any ideas about what to do in the Perl script to avoid concurrency > > problems ? > > > > This is the script: > > > > > > #!/usr/local/bin/perl > > print "Content-type: text/xml\n"; > > use CGI; > > read(STDIN, $cadena, $ENV{'CONTENT_LENGTH'}); > > > > $cadena =~ tr/+/ /; # reeplace the + sign by spaces > > > > $request = "> /myfolder/mypipe/pipe1"; > > > > unless (open(SYSREQUEST, $request)) > > { > > die("Impossible to open the pipe $request\n"); > > } > > > > print SYSREQUEST "$cadena\n"; > > > > close(SYSREQUEST); > > > > $request2 = "/myfolder/mypipe/pipe2"; > > > > unless (open(SYSREQUEST2, $request2)) > > { > > die("Impossible to open the pipe $request2\n"); > > } > > > > while ( <SYSREQUEST2> ) > > { > > print "$_\n"; > > } > > close(SYSREQUEST2); > > > > > > Thank you very much in advance, > > > > Enric > > > > > > > > -- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > > **** DISCLAIMER **** > > "This e-mail and any attachment thereto may contain > information which is confidential and/or protected by > intellectual property rights and are intended for the sole > use of the recipient(s) named above. Any use of the > information contained herein (including, but not limited to, > total or partial reproduction, communication or distribution > in any form) by other persons than the designated > recipient(s) is prohibited. If you have received this e-mail > in error, please notify the sender either by telephone or by > e-mail and delete the material from any computer". > > Thank you for your cooperation. > > For further information about Proximus mobile phone services > please see our website at http://www.proximus.be or refer to > any Proximus agent. > > > -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]