Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

How to pass the value of a variable from a child to parent with gui interface?

by ZJ.Mike.2009 (Scribe)
on Mar 13, 2010 at 02:55 UTC ( [id://828385]=perlquestion: print w/replies, xml ) Need Help??

ZJ.Mike.2009 has asked for the wisdom of the Perl Monks concerning the following question:

In the following toy program, I want to pass the value of $text in the while(1) loop from the child process to the parent's while(1) loop but nothing happens except that Perl throws me an "Use of uninitialized value" error.

Any idea how I can fix this problem? or what I might be doing terribly wrong? Thanks as always for any comments and suggestions :)

use strict; use warnings; use Win32::GUI(); my $text; my @h = qw(LINE1 LINE2 LINE3 LINE4 LINE5); my $pid = fork(); if ($pid) { my $main = Win32::GUI::Window->new( -left => 100, -top => 100, -width => 310, -height => 150, ); $main->Show(); my $display = $main->AddTextfield( -left => 60, -top => 35, -width => 180, -height => 20, ); while(1){ $display->Show(); $display->SelectAll(); $display->Clear(); $display->Append($text); Win32::GUI::Dialog(); } } elsif ($pid == 0) { while(1){ $text = "$h[int(rand(@h))]"; sleep(3); } }
  • Comment on How to pass the value of a variable from a child to parent with gui interface?
  • Download Code

Replies are listed 'Best First'.
Re: How to pass the value of a variable from a child to parent with gui interface?
by BrowserUk (Patriarch) on Mar 13, 2010 at 04:15 UTC

    Change:

    use Win32::GUI(); my $text;

    To:

    use threads; use threads::shared; use Win32::GUI(); my $text :shared;

    And see what happens.


    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.

      BrowserUK, thanks for pointing out that Win32::GUI::Dialog() is actually a loop!

      I tried the following and it seems to almost get what I was expecting:

      while(1){ $display->Show(); $display->SelectAll(); $display->Clear(); $display->Update(); $display->Append($text); $display->Update(); sleep(10); } Win32::GUI::Dialog();

      The problem is: the cursor is always busy because of Win32::GUI::Dialog(); loop.

        The dialog call is now reduntant. Try this:

        use strict; use warnings; use threads; use threads::shared; use Win32::GUI(); my $text :shared; my @h = qw(LINE1 LINE2 LINE3 LINE4 LINE5); my $pid = fork(); if ($pid){ my $main = Win32::GUI::Window->new( -left => 100, -top => 100, -width => 310, -height => 150, ); $main->Show(); my $display = $main->AddTextfield( -left => 60, -top => 35, -width => 180, -height => 20, ); while(1){ $display->Show(); $display->SelectAll(); $display->Clear(); # $display->Update(); $display->Append($text); $display->Update(); sleep(1); } } elsif ($pid == 0) { while(1){ $text = "$h[int(rand(@h))]"; sleep(1); } }

        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.

      BrowserUk, Thanks for the pointer. Now looks like the value of $text can successfully be passed to the parent at some point. But somehow this $text is not dynamically changing. I'm expecting $text can be dynamically displayed and that's why I created two infinite loops in both child and parent.

      Anyway, thanks again :)

        The problem is, this Win32::GUI::Dialog(); is a loop. It doesn't return until you do something on the dialog. If you click the close button on the dialog a few times, you'll see that the child is indeed running its loop.

        But until you understand how Win32::GUI works, trying to write multi-threaded apps using it is going to be a frustrating exercise.


        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: How to pass the value of a variable from a child to parent with gui interface?
by 7stud (Deacon) on Mar 13, 2010 at 04:27 UTC
    or what I might be doing terribly wrong?

    Processes do not share variables. Once you fork(), each process has its own copy of the variables, and any changes to the variables are local to the process. The subject you need to research is IPC (inter process communication). You might start by reading perlipc.

    Here is an example of what you can do:

    use strict; use warnings; use 5.010; my @lines = qw{ LINE1 LINE2 LINE3 LINE4 LINE5 }; my $pid = open my $INPUT_FROM_CHILD, '-|'; if (!defined $pid) { die "Couldn't fork: $!"; } if ($pid) { say 'parent: blocking until child sends some data...'; while (<$INPUT_FROM_CHILD>) { #line oriented reading chomp; say "parent: $_"; } waitpid($pid, 0); say "parent: child exited with status = $?"; say 'parent: exiting...'; } else { sleep 2; say $lines[int(rand(@lines))]; close $INPUT_FROM_CHILD; sleep 10; }
    Note the consequences to the parent, which is not something you want to do in a gui setting. The gui environments I'm familiar with--perl not being one of them--usually have a special setup for executing long running processes, which automatically signal the gui when they are done. You can then set up a listener for that 'event' and do something in response.
      Processes do not share variables. Once you fork(), each process has its own copy of the variables,

      Under win32, fork is just threads::create() in disguise.


      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.

        ...which also does not share variables. Each thread has its own copy of the variables.

        forks::shared and threads::shared does allow sharing.

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

      @7stud, thanks for pointing this out: "Processes do not share variables". I think this is the crux of my problem. I'll take a look at perlipc. Thanks :)

      BTW, I'm running ActivePerl on Windows box, your illustration code has this "open my $INPUT_FROM_CHILD, '-|';", which does not work for me. But thanks the same :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://828385]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-25 18:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found