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

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

I am working on a project where we are writing a series of Perl programs that will run unattended, while we are asleep. Those programs will be run from cron or autosys.

We have a number of situations where we are doing database operations that involve reading one table and writing another based on business rules. In some cases, we may reach a point in the processing when we want to abort the program and return an error to the calling process. We are doing this by writing an error message to a log file and performing an exit(1);.

One of the questions that keeps coming up is: Can Perl be relied upon to properly dispose of all the system resources that it was using if the program is terminated using exit()? By system resources I mean, the memory that it allocated to hold arrays or hashes, any open file handles that exist, database connections opened under DBI or Sybase::DBlib | CTlib.

Thanks for any help you can provide--

Dave Aiello
Chatham Township Data Corporation

  • Comment on How aggressively does Perl clean up when you exit()?

Replies are listed 'Best First'.
Re: How aggressively does Perl clean up when you exit()?
by grinder (Bishop) on Nov 14, 2001 at 21:31 UTC

    You can make sure your database handles are closed down correctly by calling the disconnect method in an END block.

    END { defined $db and $db->disconnect; }

    There is also a module on CPAN yclept1 AtExit that I have never used. For all I know, it predates the appearance of END blocks, but it may be worth a look.

    1. Chatterbox silliness. yclept is very olde english, meaning "named".

    --
    g r i n d e r

      END blocks have been around since the dawn of time. They were stolen^Wborrowed from awk.

Re: How aggressively does Perl clean up when you exit()?
by broquaint (Abbot) on Nov 14, 2001 at 21:14 UTC
    When you exit() from perl, it will close all open filehandles and free all variables. As for database connections, I believe it will attempt to close it, but I get the feeling that it is largely dependent on how your database driver handles disconnections. But generally it's pretty safe to exit() from perl at all but the most crucials of times (and even then it's pretty sturdy).
    HTH

    broquaint

Re: How aggressively does Perl clean up when you exit()?
by Caillte (Friar) on Nov 14, 2001 at 21:11 UTC

    The place to find out about any bugs in your release of perl is here. To my knowledge there is no current bug regarding loss of resources when perl exits, but a check here will prove conclusively and will also allow you to track that bug, showing when it gets squashed.

    $japh->{'Caillte'} = $me;

Re: How aggressively does Perl clean up when you exit()?
by Fletch (Bishop) on Nov 14, 2001 at 21:25 UTC

    If your OS doesn't clean up that type of stuff when a process exits, you probably should get a better OS. The only things I could think wouldn't get cleaned up automagically would be things like shared memory or semaphores, and you could possibly have lingering socket connections in TIME_WAIT states depending on how you set your socket options.

      I doubt there will be lingering socket connections since those are treated as FileHandles and all FileHandles should be wiped. Shared memory can be nuked by putting in this catching the INT signal like this:

      $SIG{INT} = sub { IPC::Shareable->clean_up_all ; exit 0;} ;

      You might want to catch other signals as well for this, however this catches everything I have ever run into except a perl core dump.

      Update: Hmmm, crazyinsomniac has said that you can't/shouldn't exit when catching INT. I will take his word on it, as he has been perling longer than I I'm sure. However this has been working for me in an existing implementation, maybey I'm bound for a crash!! I'll have to debug it futher.

      "Nothing is sure but death and taxes" I say combine the two and its death to all taxes!
        Try a different signal or better yet setup an END{} See perlfunc:exit.
Re: How aggressively does Perl clean up when you exit()?
by Aristotle (Chancellor) on Nov 15, 2001 at 01:26 UTC
    There is a fine difference to note here.

    On the one hand you have the "standard" resources - memory, file handles and the like; these resources are provided by the interpreter as it executes your script. These resources are also guaranteed to be cleaned up on exit() (so long as you're not dumping core or something).

    Then there's "external" resources the code in execution may have allocated - like, a database driver may have asked the database to allocate a handle. These resources will not be released automatically, rather, the code in question has to make sure they are returned. In case you're using CPAN modules, it is safe to assume that, bugs aside, all of them clean up behind themselves.

    As has been mentioned, you may want to look into what END { } and DESTROY { } do: define a blocks of code that will always be executed the end of the program or when the corresponding object goes out of scope, respectively. This is (almost) regardless of how you fall out (of the program or scope). Properly written modules (such as the ones available on CPAN :)) use these to make sure they neatly clean up after themselves.

    Long reply, short point: yes. You can use exit() to fall out of your scripts at whichever point you choose.
Re: How aggressively does Perl clean up when you exit()?
by jeroenes (Priest) on Nov 14, 2001 at 22:02 UTC
    As for how you can monitor your system resources, I would suggest lsof1 for that. Use it with the -r option while perl processes are created and killed, and you'll know whatever stays open or not. With lsof you can also monitor sockets etc.

    And you'd need 'ps' or any of the Proc modules (Proc, eg Proc::ProcessTable) to monitor memory usage. As stated elsewhere, memory cleanup depends on your OS.

    hth,

    Jeroen

    1 Assuming you are on *nix

    Update: I also come across a mac os9 utility that lists open files

        And of course the Resource Kit, I shudder to think about having to run Windows without Resource Kits.

        "Nothing is sure but death and taxes" I say combine the two and its death to all taxes!
Re: How aggressively does Perl clean up when you exit()?
by mpeppler (Vicar) on Nov 14, 2001 at 21:57 UTC
    The Sybase connections are automatically closed when the process exits.

    With the Sybase:: modules you can set a trace flag to show DESTROY calls, if you want to be able to confirm this - see the Sybase::CTlib::debug() and/or Sybase::DBlib::debug() subroutines.

    Michael

Re: How aggressively does Perl clean up when you exit()?
by fokat (Deacon) on Nov 15, 2001 at 02:39 UTC
    This is really something that falls within the responsability of the OS rather than Perl. When a process exit()s, the OS is responsible for closing all open descriptors, reclaim memory, flush caches, etc.

    You should be concerned with leaving your application in a consistent state (ie, calling ->rollback() on pending transactions, etc). This, as you might see, lies on a higher level of abstraction than closing a file of freeing a block of memory.