http://www.perlmonks.org?node_id=679048

sperlyjinx has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I'm trying to use the RSPerl module in a script that uses threads. I am able to call R functions without a problem when I don't use threads. However, using threads, I get varying errors depending on how I call the R functions. If I call the R::initR function in the "boss" thread and then try to call R functions from a "worker" thread, I get the following error: Error: C stack usage is too close to the limit Caught error in R::call() However, if I move the "use" declarations for R & RReferences to the worker thread, along with the initR call, I get this: Fatal error: R home directory is not defined I've attached some code for your reference. Is there any way to get this module working with Perl threads? Thanks in advance for your help. -Jay
#!/usr/bin/perl use warnings; use strict; #use R; #use RReferences; #&R::initR("--silent"); use threads; use threads::shared; use Thread::Queue; our $queue : shared = Thread::Queue->new; our $hold : shared; my $thr = threads->new (\&command_runner); $hold =1; $queue->enqueue("ls"); while ($hold) { sleep(1); } $queue->enqueue("end"); $thr->join(); # Thread for processing functions sub command_runner { use R; use RReferences; &R::initR("--silent"); my $run = 1; # run until return while ($run) { # This call will block until the main thread sends the job my $job = $queue->dequeue; print "j: $job\n"; if ($job eq "ls"){ R::ls(); } elsif ($job eq "end") { $run = 0 } { lock $hold; $hold = 0; } } }

Replies are listed 'Best First'.
Re: RSperl & threads
by renodino (Curate) on Apr 08, 2008 at 19:50 UTC
    Caveat: I know nothing about RSPerl, other than it embeds one interpretter in the other.

    Since each Perl thread starts a new interpretter, its unclear whether an R interpretter created in the main thread will get cloned into all the children, or each child will get a brand new R interpretter instance.

    Assuming you revert to the original approach, you might try cranking up the per-thread stack size, and see if that corrects the error message. Note that doing so will reduce the number of threads you can start.


    Perl Contrarian & SQL fanboy
Re: RSperl & threads
by zentara (Archbishop) on Apr 08, 2008 at 21:26 UTC
    I couldn't find the R or the RReferences module on cpan. There probably is a way to make it work with threads, but reading the reviews of Statistics::R module, it is problem prone on it's own, even without threads.

    Since it involves a "shell" you may need some kind of pty, or pipes, to run it from Perl thru IPC.

    See if you can get it to work thru a forking mechanism first, until you get a handle on what is exactly happening, and then try to convert to threads.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: RSperl & threads
by zentara (Archbishop) on Apr 10, 2008 at 13:53 UTC
    I was just meditating last night, and thought about your problem. I had a thought( better duck :-) ). If the RSPerl is an interpreter, which you send commands to stdin and get results out of stdout, you probably should run it thru IPC::Open3. I have sample code below
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; $|=1; #my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/bash'); my $pid=open3(\*IN,\*OUT,0,'/bin/bash'); # set \*ERR to 0 to send STDERR to STDOUT my $cmd = 'date'; #my $cmd = 'top'; #send cmd to bash print IN "$cmd\n"; #getresult my $result = <OUT>; print $result;
    Now you should be able to do a similar thing with the RSPerl interpreter. Of course, in a real script, you may want to separate stdout and stderr, and use IO::Select. Search for examples of IPC::Open3 for more detailed usage.

    Now, once you get IPC::Open3 to run the interpreter, you can put the code into a thread, and pass in strings to be eval'd thru ther shared variable mechanism.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks to everyone for your input. I've solved the problem a slightly different way. I was able to set up a socket connection between R & Perl. If anyone is interested in the Perl or R code that accomplishes this, please let me know.
        Hi, could you please share the code with us all? I am a biologist used to working in R environment for my statistical analysis. But, now I have to call my .R files from perl. I have tried using RSperl, but it doesn't seem to support source("filename.R") function. Any take on this? Your comments are highly appreciated.
        Yes, I am interested in the Perl and the R code. Thank you very much.
        i would be very interested in this code. can you post it up on here or send it to me directly?