in reply to How to skip END blocks with threads?

Like this?

use warnings; use strict; use threads 'exit' => 'threads_only'; my $ppid = $$; END { return unless $$ == $ppid; print "this should print once\n" } if (fork) { print "parent\n"; sleep 1; } else { print "child\n"; threads->exit; } print "last line of program\n"; __END__ c:\test>junk2 parent child last line of program this should print once

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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: How to skip END blocks with threads?
by spx2 (Deacon) on May 04, 2009 at 13:17 UTC
    and you're mixing threads with forks now ? is this good or bad , I can't tell
      and you're mixing threads with forks now?

      Under windows, they are the same thing!

      fork is emulated using threads.

      Besides which, the only reason I need to use threads, is to import the threads->exit call, which simply terminates the current thread (fork-emulation) without terminating the process as exit or POSIX::_exit() would.

      is this good or bad, I can't tell

      I'm no great lover of the fork emulation--is has too many caveats to be particular useful--once once you've chosen to go that route, you're already using threads implicitly, so importing the extra routine to achieve the goal just makes sense.


      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.
Re^2: How to skip END blocks with threads?
by repellent (Priest) on May 05, 2009 at 02:23 UTC
    Thanks, that works great. Unfortunately, I cannot affect the way the END block(s) are written.

    I'm trying to have my module IPC::Exe avoid doing END blocks once exec fails in a child, so it doesn't act in a surprising way. From the looks of it, I may just abandon the idea (in favor of consistency) because I can't tell when threads are used.

    exit and die seem to do the right thing when called inside a thread or a different process, but they also do END.
      Unfortunately, I cannot affect the way the END block(s) are written.

      Then add an END block in your code, prior to useing the modules (any modules), whos end blocks you wish to disable, and call thread->exit() within that END block. Eg.

      #! perl ... # main.script my $originalPid = $$; END{ return if $$ == $originalPid; require threads; threads->exit; } use Foo; use Bar; ...
      • By putting your END block ahead of any modules you use, you ensure that your END block is called first.
      • If the curent pid == the pid when the code first ran, you are the parent, so quit early and allow the parent to run any END end blocks set up by the modules it uses.
      • Otherwise, you are a child, so call threads->exit before any other END blocks are called.

      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.
        Actually END blocks goes in LIFO order, which works out even better :) Let me experiment with your idea. Thanks again!
      When modules are loaded (like threads), they leave an entry %INC (besides creating an entry in %::)