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

Hi PerlMonks I would be very grateful for some advice.

I have a perl program running in windows that forks a child process. The child process opens a file handle $fh and starts some work with the file.

A short while later the parent forks a second child process. Much to my surprise the file opened in the first child is also opened in the second child according to process explorer (although I doubt the file handle created in the first child is shared) The first child finishes its work and closes the file handle and finishes. Annoyingly though the file stays open till the second child has completed and finished. I don't want this. The files are temporary and I need to be able to delete them without another child locking them.

I know that file handles are passed from parent to child processes. I wasn't expecting anything created in 1 child being locked by the second though.

Any help much appreciated.

Replies are listed 'Best First'.
Re: File handles with forked processes
by BrowserUk (Patriarch) on Oct 10, 2015 at 00:05 UTC
    Annoyingly though the file stays open till the second child has completed and finished. I don't want this.

    Then close the open filehandle in the parent once you've spawned the first child; then it won't be replicated into any other children you spawn.


    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". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: File handles with forked processes
by Anonymous Monk on Oct 09, 2015 at 23:38 UTC

    Much to my surprise the file opened in the first child is also opened in the second child according to process explorer (although I doubt the file handle created in the first child is shared)

    This is the promise of fork, even of emulated fork, clone everything, so this is what you should expect to happen.

    Maybe you want to fork before opening file handles?

    or not fork at all , spawn a background process Proc::Background...?

      Specifically, the fork Posix system call makes an exact copy of the parent process, including all memory segments. Both the parent and the child resume execution exactly as if they had each made the fork system call. Usually, program switches execution paths based on the return value of the fork call in order to learn whether it is the child or the parent.

      You are running Windows, which doesn't have the fork system call, so you are using Perl's emulation of it within the Perl interpreter. To learn more about the limits of this emulation, run perldoc perlfork or read the perldoc page here.

Re: File handles with forked processes (SetHandleInformation)
by tye (Sage) on Oct 11, 2015 at 22:07 UTC

    See SetHandleInformation() and HANDLE_FLAG_INHERIT in Win32API::File, which will require the use of GetOsFHandle().

    - tye        

      See SetHandleInformation() and HANDLE_FLAG_INHERIT

      That won't work as it only affects the inheritance of handles across CreateProcess() calls; not the CreateThread() calls that underly fork on Windows.


      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". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Yeah, it wasn't clear to me whether the original poster was being sloppy with terms like "child process" or with the term "fork".

        This makes me wonder if emulated fork on Windows (native) Perl obeys $^F when duplicating interpreter instances for new threads. Seems like it doesn't, which is weird (to me). Update: Oh, right, $^F applies to exec, not to fork().

        Sentences like "The files are temporary and I need to be able to delete them without another child locking them" make me think of using Win32API::File's createFile() to open the file w/o preventing the deleting (or renaming) of the file. You would likely follow that with OsFHandleOpen() which would cause Perl do duplicate the resulting Perl file handle when creating threads. My guess is that Perl's emulated fork() uses fdopen() to duplicate file handles and I suspect that such would not impose locking against delete/rename if such is missing from the original handle. But I've never checked either of those points.

        Not that I'm claiming that such is the best solution, just adding information (and even more questions).

        - tye        

A reply falls below the community's threshold of quality. You may see it by logging in.