in reply to Re^3: Perl/Tk repeat method, callback doesn't work if...
in thread Perl/Tk repeat method, callback doesn't work if...

There isn't a clear specific reason for posting the following text, but at least I want to thank you zentara for your useful posts and all readers;
moreover, my small experience with Tk could benefits from any type of comment to this post and moreover... the discussion could be useful to others...
So, Due to my No experience with Tk I don't know if there is a better way to accomplish my work, anyway my code is very confusing so I only briefly explain its scheme and I'll be pleased to receive any feedback on what the reader think about it and if he knows a simpler/better way:

1. The program Starts and load threads module (one thread only for all "Worker" functions, Tk run in the main (not threaded))

2. Define some shared vars used to manage Input from GUI, Output from "Worker thread" and state of "Worker thread"

3. Launch the "Worker Thread" (when it starts, it loads some settings and enter an infinite loop timed by select, at each cycle it checks a shared variable which give the ID of function to launch}

4. Open a Block { where loads Tk Module; whole Tk GUI resides here }

5. Each Time the user Launch a function, FUNC_CTRL subroutine (placed in the GUI Block) run and create the List of smaller functions needed and defined in "Worker thread"; so manage that "Stack" and opening/closure of MsgBox, Dialog Box, Refresh of the right Tk fields

6. Some shared variables filled by the "Worker" and reelaborated by different subroutines for each function to give out the right form of output in the right place (GUI Fields).

The Timers problem I think to have fixed, comes from inside the FUNC_CTRL fuction that manages the $MW->repeat object for each MsgBox, refresh etc, from creation to destruction, so it needs to know when they are up and runnig before free the "Worker Function", I did that this way:
my ($MSGBOX) = &MSG_WIN(); # Create the MsgBox Object and the repeat t +imer inside which $STATE_of_MSGBOX_TIMER is changed. Return the MsgBo +x object $MW->waitVariable(\$STATE_of_MSGBOX_TIMER); # This should wait until M +essage Box Timer is started


I created one thread only because starting a new one each time for each function show me the grow of used memory, and "detach()" or "join()" the thread doesn't free the memory, so it accumulates.

Replies are listed 'Best First'.
Re^5: Perl/Tk repeat method, callback doesn't work if...
by zentara (Cardinal) on May 19, 2011 at 18:10 UTC
    You are right to use your thread that way, with Tk. Your code is kind of complex from the description, so without REAL code examples, we can only hypothesize. :-)

    The key idea is the eventloop and how it allocates time to the various widgets. You might want to experiment with sprinkiling

    DoOneEvent(); # and or $mw->update;
    after variable updates which are needed elsewhere as signals.

    Also, with threads shared variables, the main thread is NOT automagically updated with the shared variable changes. The shared variable must be actively read, for it to cross the thread boundary.

    So if $STATE_of_MSGBOX_TIMER has changed in the thread, the main thread dosn't know about it, until it reads it once. If I understand your code idea, you are trying to use that in waitVariable, but it may not have been updated properly across the thread. So I don't know if a threads shared variable can be used across threads in waitVariable.

    A quick hack to tell if that's the case, is to make a timer in the main thread, that automatically updates all shared vars frequently, like

    $mw->repeat( 10 , { my $dummy_var = $STATE_of_MSGBOX_TIMER });
    that will force the main thread to read the shared var every 10 milliseconds.

    Good luck.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh