How can I send messages (or signals) from a parent process to a child process and viceversa in Perl?

匆匆过客 提交于 2019-12-11 01:42:39

问题


Im writing a program that manage muti-processes. This is what I have done and its working great! but now, I want to send messages from the child processes to the parent process and viceversa (from the parent to the childs), do you know the best way? Do you know if what I have done is the proper way for what I want (send messages, or signals or share memory from the child processes to the parent process and viceversa)?

Thanks in advance!!


#!/usr/bin/perl -w
use strict;
use warnings;

main(@ARGV);

sub main{
    my $num = 3; #this may change in the future (it would be dynamic)
    my @parts = (1,4,9,17,23,31,46,50);
    my @childs = ();

    while(scalar(@parts)>0 || scalar(@childs)>0){
        if(scalar(@parts)>0){
            my $start = scalar(@childs) + 1;
            for($start..$num){
                my $partId = pop(@parts);
                my $pid = fork();
                if ($pid) {
                    print "Im going to wait (Im the parent); my child is: $pid. The part Im going to use is: $partId \n";
                    push(@childs, $pid);
                } 
                elsif ($pid == 0) {
                    my $slp = 5 * $_;
                    print "$_ : Im going to execute my code (Im a child) and Im going to wait like $slp seconds. The part Im going to use is: $partId\n";
                    sleep $slp;
                    print "$_ : I finished my sleep\n";
                    exit($slp);
                } 
                else{
                    die "couldn’t fork: $!\n";
                }   
            }
        }

        print "before ret\n";
        my $ret = wait();
        print "after ret. The pid=$ret\n";

        my $index = 0;
        for my $value (@childs){
            if($value == $ret) {
                splice @childs, $index, 1;
                last;
            }
            $index++;
        }
    }

}


回答1:


Use kill. If you set a variable in the parent before your fork, you don't need any external options.

my $parent_pid = $$; # Keep a reference to the parent

my $pid = fork();
if ($pid) {
    print "Im going to wait (Im the parent); 
    my child is: $pid. The part Im going to use is: $partId \n";
    push(@childs, $pid);
} 
elsif ($pid == 0) {
   my $slp = 5 * $_;
   print "$_ : Im going to execute my code (Im a child) and Im going to wait like $slp seconds. The part Im going to use is: $partId\n";
   sleep $slp;
   print "$_ : I finished my sleep\n";

   kill 20, $parent_pid # Send a signal to the parent, 20 is SIGCHLD

   exit($slp);
} 

See perldoc -f kill for more details on the kill call Another option if you need to do more complex things is to use POE




回答2:


Forks::Super has a good interface for passing messages between parent and child processes (interprocess communication). With this interface, you can pass messages to the child's STDIN and read from the child's STDOUT and STDERR handles.

use Forks::Super;

# set up channels to child's STDIN/STDOUT/STDERR with blocking I/O
my $pid = fork { child_fh => 'all,block' };

if ($pid) { # parent
    $pid->write_stdin("Hello world\n");
    my $msg_from_child = $pid->read_stdout(); # <-- "HELLO WORLD\n"
    print "Message from child to parent: $msg_from_child";
} 
elsif (defined($pid) && $pid == 0) { # child
    sleep 1;
    my $msg_from_parent = <STDIN>;            # <-- "Hello world\n"
    my $output = uc $msg_from_parent;
    print $output;
    exit 0;
} 
else{
    die "couldn’t fork: $!\n";
}   


来源:https://stackoverflow.com/questions/4035689/how-can-i-send-messages-or-signals-from-a-parent-process-to-a-child-process-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!