Can I use POSIX signals in my Perl program to create event programming?

Are there any POSIX signals that I could use in my Perl program to create event-driven programming? I currently have a multiprocessor program that can cross talk, but only one child can listen to my parent stream at a time.

foreach (@proc) { sysread(${$_}{'read'}, my $line, 100); #problem here chomp($line); print "Parent hears: $line\n"; } 

The problem is that the parent sits in a continuous state of waiting until he receives a signal from the first child before he can continue. I rely on the “pipe” for my connection.

My current solution is very similar to: How can I use `pipe` to facilitate interprocess communication in Perl?

If possible, I would like to rely on the $ SIG {...} event or any solution other than CPAN.

Update:

As Jonathan Leffler mentioned, kill can be used to send a signal:

kill USR1 => $$; # send yourself SIGUSR1

My solution would be to send the signal USR1 to my child process. This event tells the parent to listen to a particular child.

child:

 kill USR1 => $parentPID if($customEvent); syswrite($parentPipe, $msg, $buffer); #select $parentPipe; print $parentPipe $msg; 

Parent:

 $SIG{USR1} = { #get child pid? sysread($array[$pid]{'childPipe'}, $msg, $buffer); }; 
  • But how do I get the source / child pid that signals the parents? Ask the child to identify himself in his message.
  • What happens if two children simultaneously signal USR1?

Update 2: Solution

I went with a choice that used a vector approach for non-blocking I / O. For those who encounter this thread, check out: http://docstore.mik.ua/orelly/perl/cookbook/ch07_14.htm , as it covers both the vector path and the IO :: Select module. I understand that the IO :: Select module would be more elegant, but I was more interested in learning about the new Perl mechanics. Thank you all for your help.

Render:

 $rin = ''; # repeat next line for all filehandles to poll vec($rin, fileno(FH1), 1) = 1; vec($rin, fileno(FH2), 1) = 1; vec($rin, fileno(FH3), 1) = 1; $nfound = select($rout=$rin, undef, undef, 0); if ($nfound) { # input waiting on one or more of those 3 filehandles if (vec($rout,fileno(FH1),1)) { # do something with FH1 } if (vec($rout,fileno(FH2),1)) { # do something with FH2 } if (vec($rout,fileno(FH3),1)) { # do something with FH3 } } 
+4
source share
3 answers

You can use select to monitor communication channels (note: if you use Win32 select, you can only use it on the socket).

So you can use this code:

 use IO::Select; use IO::Handle; ... $_->blocking(0) for @handles; while( 1 ) { my $s = IO::Select->new( @handles ); for my $h ( $s->can_read( 1 ) ) { my $data = read_handle($h); process_handle_data( $data ); } } sub read_handle { my $h = shift; my $got = ''; 1 while read( $h, $got, 1024, length $got ); return $got; } 

Take a look at the UDP example in perlipc. It uses the built-in select. I prefer the main IO::Select module for the built-in select , it is much easier to read.

Update: You really should consider using an event framework such as POE, Event, or Coro. There's a pretty good list of options in this perlmonks stream . Do not be afraid of CPAN.

+4
source

If you want to run event-driven programming, take a look at one of the CPAN event modules, such as POE , Coro, or AnyEvent, think of what you have to do.

+9
source

To answer a direct question, SIGUSR1 and SIGUSR2 are for "user-defined" purposes, so you can use them.

You might be better off looking at an existing system.

+2
source

Source: https://habr.com/ru/post/1305903/


All Articles