Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

How to reduce memory by killing redundant perl executables

by juo (Curate)
on Jul 13, 2001 at 15:42 UTC ( #96354=perlquestion: print w/replies, xml ) Need Help??

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

I have different perl scripts who are launched from within a Perl script that run all independant what means if a certain Perl script is launched from within another Perl script that script have to be killed straight after launching the other script without leaving any trace. With the subroutine below I have been able to do this except for the fact that the Perl executable stay into memory which means that everytime I go through the subroutine below it creates a new Perl executable in memory so after a while I got a lot of Perl executables running. When I exit the Perl script currently active it will kill all remaining Perl.exe. Is their a way that I can launch another Perl script from within a Perl script killing that script without killing the system call to launch the other script. I know that it is very difficult explained to do something simple. It's basically automatic exiting a Perl script and launching another one. The scripts are not running from windows but from an application that has a Perl interface.

sub manual_gerber_auto { $W->destroy; system "perl $GENESIS_DIR/sys/edesign/scripts/"; exit; }

Replies are listed 'Best First'.
Re: How to reduce memory by killing redundant perl executables
by dragonchild (Archbishop) on Jul 13, 2001 at 16:20 UTC
    using exec instead of system will transfer control to the second script. This means that only one script will be running at any given time.
      Per a request from the Chatterbox, it can never hust to have a brush up on the diffrences between system() and exec(). While the internal implimentation depends on the operating system, here are the genral diffrences :

      system(): The system($command) command does the same thing as typing a command at the prompt in unix. A new child process is created, the program itself is loaded (be it /bin/ls or /usr/bin/perl), and begins processing (i will ignore the calls at a level lower than that).

      exec(): The exec($command) call is quicker, because rather than creating a child process, and then loading the program to be run, it instead loads the program to be run into the current memory space. This means that if, running under pid 3 does exec("ls"), then the perl program will be unloaded from memory and the machine code for ls will be loaded in it's place, and will begin running under pid 3.

      So, in short, system() creates a new process, in fresh memory.while exec() replaces the current program with the new one. An interesting note is that when using exec, the stdin, stderr and stdout are passed to (rather, inherited by) the new process, so reopening them will effect the next program.
      OH, a sarcasm detector, thatís really useful

      The perl scripts are launched from within another application that supports Perl scripting so the moment I start using exec the interaction with that application is lost also. I only want to kill the Perl script.

        Now, I'm thoroughly confused as to your setup and what you want to do with it. What exactly is this "other application"? Why is it launching perl scripts? Why is memory such an issue?
Re: How to reduce memory by killing redundant perl executables
by Abigail (Deacon) on Jul 13, 2001 at 17:30 UTC
    If this is the code you are actually using, then I will assume there is a problem with the program (assuming you want the program to survive its parent). See, if you do a system, Perl will launch the program you gave it as an argument and then wait for the launched program to complete before continuing with the next statement. Hence, by the time it gets to the exit, the launced program has terminated.

    This however doesn't seem to match your description. Your description however of what you have and what you want are too confusing for me, and I don't understand what your goals are.

    -- Abigail

      Abigail seems to have hit the nail on the head; the "excess" perl processes you're seeing are the parents of all the child processes created by system.

      As suggested, think about exec

      I am running Perl from an non-Perl application which you can call the parent script. From that script I launch a child script. The application is locked as long as my child script is running. As long as the child script is running the script interact with the parent script. When I run from the child script another child script I cannot use exec because then I also loose the interaction with my parent script. So I only want to kill my child script without loosing the link with my parent. When I use system it's all working fine but it builds up a lot of Perl.exe (windows2000) into the memory without releasing them.

        Let me recap and see if I understand you right.

        You have a non-Perl application, which we will call the "parent". From "parent", you call a Perl program, which we will call "A". From "A", you call another process, called "child". From "child", you call yet another process, which we call "grand child".

        Now, "child" communicates with "parent". But now I am getting confused. You say that you do not want to lose the communication between "child" and "parent", however, you also want to kill "child". So, I am not certain which one you want to get rid of.

        You also say you lose the communication if you exec "grand child", which isn't strange because an exec replaces the current process, it being "child". So, you use system and that works fine, but it leaves running processes behind. Well, of course that "works fine". Now you are not getting rid of "child", just as I said in my previous post. Because you are doing system, "child" will wait till "grand child" is finished before executing the next statement, which happens to be the exit. So.... "child" doesn't go away until "grand child" is finished. But isn't that exactly what you want? Because if "child" goes away your communication is broken anyway....

        -- Abigail

        Let me see if I understand this:
        1. You have an application that isn't Perl.
        2. You run from this application some Perl script.
        3. From the Perl script, you launch another Perl script.
        4. The parent and child scripts talk to one another.
        5. At some point, you wish to be able to launch a grandchild script.
        6. This grandchild script may or may not need to be able to talk to the child script.
        *blinks* I'm going to say right now that this is starting to sound like a poorly-designed application. Without seeing your code, I'm going to bet that you are calling the grandchild script when you probably should have it as a module that you use in the child script. I'm guessing that you have these grandchildren scripts to add functionality, depending on a series of possible outcomes.

        It sounds like you may need to explore modules and redesign the way you're doing things.

        (Please note that you have given very little information about what you're doing and how it's implemented. If you know about modules and are using them, then I apologize for any insult you may feel I have given you.)

Re: How to reduce memory by killing redundant perl executables
by mvaline (Friar) on Jul 13, 2001 at 15:52 UTC

    I am only a humble scribe, but if I remember correctly, the system function creates a child process and the exec function should actually fork. If you use exec, I think you should be able to kill off the first script without damaging the second.

    However, if you are running Windows, I suppose things might be different; I've heard that Windows can't really fork.

    Updated:Ah, my mind was obviously foggy when I wrote that: obviously my notions of forking were all messed up. Perhaps someone wiser than I would be so kind as to explain *exactly* what happens when both of these functions are executed.

      Quick overview of Unix syscalls :-)

      system creates a new process, a child of the current process, with its own PID, memory, etc. This might be called directly in Perl using the system @list method (e.g.  system 'myprogram', 'xyz' , or (better?)  system { 'myprogram' } 'myprogram', 'xyz' , or perl might go and run a shell to interpret it if you use the system $scalar form, to interpret things like wildcards, etc. (e.g.  system "ls ~/tmp/tempfile.*" ).

      system is "high-level" (-ish) magic to cover up fork and exec. fork essentially "clones" the current process, making a new one with its own PID, memory, etc. which are duplicates of the parent. The only difference is that the parent's call to fork returns the PID of the child, and the newly-cloned child (which continues running from the fork call that created it) gets back a "0." (In real life, OS designers do all sorts of magic so that a fork syscall doesn't immediately double the in-memory size of a program, but they do it so well that it doesn't matter that they're faking it.) You can then exec another program: this removes the entire binary image of your program from memory, replacing it with the other program, but it inherits your PID and other process-based descriptors. In Perl, exec has the same kind of magic with regards to shells as system.

      This is hearty magic, because you can do things like "cripple" your forked child process before exec'ing another, e.g. by setting resource limits, reducing its priority, chroot'ing it into a subdirectory so that it can't get at the rest of your filesystem, and other lovely things.

      All of that is Unix (POSIX, Linux, etc.) magic. The Win32 system is based not upon fork and exec, but upon (and this is from vague memories of stuff I never use, so somebody slap me if I'm totally off-base here) the "kernel" (some blend of KERNEL23, WIN, SYSTEM32, USER, &c.) starts each process into its own process space using WinExec, which always performs its own sort of shell magic (like "executing" a document by launching an associated application, rather like the Linux "binmisc" toys that launch Wine when you double-click a Windows .EXE file on your desktop, etc.). More or less, WinExec is exactly what you get from the Start/Run... dialog.

      Since there's no 'real' fork, and fork is heavily used by Unix programs, the perlguts wizards implemented it on Win32 using threads. "Threads" are (sort-of) like processes, except that all threads running in one program share the same memory, even if they have different thread ID's that work rather like PID's and can have certain things associated with them.

      I haven't monkeyed around much with Win32-Perl for anything that complex, but I've heard that in v5.6+ the emulation of fork is good enough for most things, so you can once again forget the way it "really works" and rely upon the magic that the perlguts are doing for you. Until it breaks.

Re: How to reduce memory by killing redundant perl executables
by mvaline (Friar) on Jul 13, 2001 at 17:25 UTC
    You might find it helpful to read perlipc. There is a very interesting section called "Complete Dissociation of Child from Parent" and the section following it called "Safe Pipe Opens" in which it demonstrates how to make your single program go multiprocess.
Re: How to reduce memory by killing redundant perl executables
by mvaline (Friar) on Jul 13, 2001 at 17:16 UTC
    Have you tried running the script in the background? system "perl $GENESIS_DIR/sys/edesign/scripts/ &";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://96354]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2019-08-24 09:35 GMT
Find Nodes?
    Voting Booth?

    No recent polls found