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

Ok, I have fork working on win32. That's no problem. I downloaded the right version (5.6.0 bld 623) from activestate and fork works great. I even have it working with LWP so I can get a page in a child process and not interfere with the parent. The only problem is, when I try to exit the child, it wants to destroy something in the parent that is related to Tk. I do know that I want to use POSIX::exit(0) or just CORE::exit(0) but those have the same problem as just calling exit.

If I don't create a MainWindow, and just do a regular non gui perl script on windows, it works great to go get a web page in the background. See below. If you uncomment out the MainWindow creation line below though, it fails on the exit of the child and gives the error:

Attempt to free non-existent shared string at Widget.pm line 96 during global destruction

Here is the code:

#!/usr/local/bin/perl use POSIX; use POSIX ":sys_wait_h"; use Tk; use LWP::UserAgent; use URI::URL; my $ua = LWP::UserAgent->new; #my $mw = MainWindow->new(); if (!($pid = fork)) { $url = 'http://www.worldmusic.de/perl/dclpc-faq.html'; $file = 'web.txt'; my $req = HTTP::Request->new(GET => $url); $req->header('Accept' => 'text/html'); $res = $ua->request($req, $file); print "hi there, i'm a child about to exit\n"; POSIX::exit(0); } print "i'm the parent about to mainloop\n"; foreach $i (0..3) { sleep 4; print "i'm the parent about to mainloop\n"; } MainLoop;
Thanks for any help!!! Justin Eltoft

Replies are listed 'Best First'.
Re: fork, tk, win32
by wog (Curate) on Jun 03, 2001 at 18:48 UTC
    The problem your experiencing is caused by the fact that Tk's just enough aware of threads to compile, and Win32's fork uses threads, and not truly seperate processes like UNIX. When your application exits, Tk's destruction routines get called. Apparently Tk gets confused with multiple threads, and that causes your problem.

    The easiest solution to this problem is to move your Tk stuff to after the code for the child in your program. That is after the if. That should prevent Tk needing to call the destruction routines in the child.

    Update: To be more specific, the problem is caused by a Widget (MainWindow) being in exsitence for the child when it exits. A look at the tk source code indicates that the use Tk does not appear to be a problem.

      Thanks! That's the most info I've gotten in a while. I really appreciate it.

      You're totally right about putting the mainwindow after the if. I even just added a button and all is fine. I wonder though if this will help me in my final app. I will need to have a gui created, and then when they click "update" I want to go get a web page using fork, and use the results to show new stats on the gui basically. Can I just put the fork in a subroutine above the definition of the GUI? I guess I don't know enough to know if that would make a difference. If not, any thoughts on how to make that work? Thanks again!!!

      Justin

        With Tk, you probably want to look at the documentation for Tk::fileevent. One solution is to use the pipe or socketpair function to generate streams from your parent to your child and vice-versa. (perlipc gives an example of this under the heading Bidrectional Communication with Yourself.)

        The idea would be is that your child could act as a server, recieving notification from the parent when an update is needed. Then it could send the information back to the parent which could know its there from Tk::fileevent. (so the parent could do it within the Tk event loop.)