[prog] perl IPC

Caroline Johnston johnston at biochemistry.ucl.ac.uk
Fri Mar 26 18:13:51 EST 2004


Hi,

I'm trying to get a perl cgi script to use R to do some stats on user 
supplied data. I can do this fine by using backticks and calling R with a 
script to run (I have a template which I'm parsing as appropriate using 
Text::Template). The problem is, I want to run a few scripts, depending on 
what information the user wants. I could do this like:

(if user wants)
$res1<-`R < $script1`;

(if user wants)
$res2<-`R < $script2`;

but it takes a reasonable amount of time for R to start up, get the data
and put it into a suitable format for analysis. I really only want to do
this once, as all the R scripts work on the same data. I suppose I could
save the data as an RData file, which would be faster than starting from
text files each time, but what I really want to be able to do is start an
R session and pass it commands when I feel like it. At this stage, I don't
need the output until I'm done with R, but ideally I would like to be able
to have an interactive R session running, so I could pass it some
commands, get the output, pass it some more commands depending on that
output.

I've tried googling for this, and am now more confused than I was to start
with. I've read stuff on fork and exec and pipes and piped opens and open2
and the perils of deadlock, and have come to the conclusion that I'm in
way over my head. I don't even know if I'm looking at the right topics. I
tried using the code below (from the cookbook) and I think I've now got 2
way communication between 2 processes, but I don't really understand how
to run R and have it use R_RDR and R_WTR as its input and output. In fact,
I'm not really sure this is what I want to be doing at all.

If someone could suggest a good tutorial on this kind of stuff (given 
that I've read the entire IPC chapter in the cookbook and failed to 
understand most of it) or give me some examples that do something similar, 
I'd really appreciate it.

Many thanks,

Cxx.

pipe(PERL_RDR, R_WTR);
pipe(R_RDR, PERL_WTR);
PERL_WTR->autoflush(1);
R_WTR->autoflush(1);

if (my $pid =fork)
{
   #Parent code here, writing to child_wtr reading from child_rdr
   close PERL_RDR; close PERL_WTR;
   print R_WTR "source('test.r')\n";
   chomp(my $line = <R_RDR>);
   print "Perl $$ read this: '$line'\n";
   close R_RDR; close R_WTR;
   waitpid($pid,0);
} else 
{
   #child code here, writing to parent_wtr reading from parent_rdr
   die "cannot fork: $!" unless defined $pid;
   close R_RDR; close R_WTR;
   chomp(my $line = <PERL_RDR>);
   print "R $$ just read this: '$line'\n";
   print PERL_WTR "R is sending this\n";
   close PERL_WTR; close PERL_RDR;
   exit;
}




More information about the Programming mailing list