Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How can I run a piece of code asyncronously in Perl?

by Doctrin (Beadle)
on Nov 02, 2012 at 17:48 UTC ( [id://1002016]=perlquestion: print w/replies, xml ) Need Help??

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

Hello everyone! I am a newbie to Perl and I want to run some code like following. t1.pl makes some actions that takes pretty long time. t2.pl calls it:
`t1.pl "arg1" "arg2" "arg3"`; print "DONE\n";
How can I run the second line of code in t2.pl asynchronously, so that "DONE" output would appear immediately, and t1.pl does it's work in background, or however? In general, would you please tell me how can I run lines of code asyncronously? Thanks in advance.

Replies are listed 'Best First'.
Re: How can I run a piece of code asyncronously in Perl?
by BrowserUk (Patriarch) on Nov 02, 2012 at 17:59 UTC

    threads

    use threads; async { `t1.pl "arg1" "arg2" "arg3"`; }->detach; print "DONE\n";

    Note: It doesn't make much sense to use backticks if you do nothing with the returned output; but that's not the subject of the question.

    And having the first script end immediately after starting the second doesn't make much sense in isolation either -- why not just run the second script directly. But I assume this is just a generic example to satisfy the "where's your code" crowd.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong

      Thanks. I'm sure it would work, but, if t2.pl would execute, say, in 0.1 sec, and the code in t1.pl would execute in 2.0 sec - it won't work (( Thread would be terminated, I suppose (( I need t1.pl to run completely independently of t2.pl which calls it...
        t won't work... Thread would be terminated, I suppose.

        Why "suppose"? Did you try it?

        C:\test>perl -Mthreads -E"async{ qx{perl -E\"sleep 5; die q[Now I'm do +ne];\"} }->detach; select'','','',0.1; die 'I\'m done'" I'm done at -e line 1. C:\test>Now I'm done at -e line 1.

        So long as you give the thread chance to start the command running, it will complete even if the thread dies.

        Ie. "t1.pl runs completely independently of t2.pl".

        It's probably not how I would do it; but then 'it' -- as you've defined it so far -- is so completely pointless, I probably wouldn't do it at all.

        But if I did, on Windows I'd probably use system 1, 't1.pl arg1 arg2 arg3';


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        RIP Neil Armstrong

Re: How can I run a piece of code asyncronously in Perl?
by pemungkah (Priest) on Nov 02, 2012 at 22:29 UTC
    If you're running on a Unix-ish system (not Windows), you can use the fork-and-exit trick to essentially make your subtask a child of init instead of your script, running it almost exactly as if you'd run it in the background from the shell: Re: Reaping Zombies (dont wanna wait).

    This will run the code as an independent process; no memory will be shared between the new process and the old one. If you need to do that, threads are better.

      Wow. This is exactly what I was trying to say. TYVM!
Re: How can I run a piece of code asyncronously in Perl?
by aitap (Curate) on Nov 02, 2012 at 19:25 UTC
    TIMTOWTDI:
    if (fork==0) { exec qw{t1.pl arg1 arg2 arg3}; }
    This will fork the program and start your command in the child process (where fork returns 0).
    Sorry if my advice was wrong.

      This TIMTOWTDI is probably better than the other WTDI. But I'd like to make it clear to the OP that exec() takes a list, so therefore:

      exec 't1.pl', $arg1, $arg2, $arg3;

      (Well, better in the sense that I cringe whenever something goes through sh -c when not absolutely necessary. It is very easy to introduce a bug that way.)

Re: How can I run a piece of code asynchronously in Perl?
by Lotus1 (Vicar) on Nov 02, 2012 at 19:09 UTC

    The word asynchronous is usually used for communication systems that are not synchronized by a clock signal. What you are asking for would be called parallel processing. If all you really want is the text to appear immediately how about this?

    print "DONE\n"; `t1.pl "arg1" "arg2" "arg3"`;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1002016]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-25 07:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found