Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

threads crash on XP (in Tk script)

Status
Not open for further replies.

MoshiachNow

IS-IT--Management
Joined
Feb 6, 2002
Messages
1,851
Location
IL
HI,

Running a Tk script on my XP I always get an error.

Code:
########################################################################################
#use warnings;
use strict;
use Win32::OLE qw( in );
use Win32::Lanman;
use Net::Domain qw(hostname hostfqdn hostdomain);
use Socket 'inet_ntoa';
use Sys::Hostname 'hostname';
use Data::Validate::IP qw(is_ipv4);
use Net::Ping;
use Tk;
use Tk::Text;
use Tk::Scrollbar;
use Tk::Pane;
use threads;

threads->create(sub { print("I am a thread\n"); })->join();

Error:
I am a thread
Free to wrong pool 1822b00 not 222770 during global destruction.

Any ideas?
Thanks

Long live king Moshiach !
 
From my experience, Tk and threads don't get along. It seems that if you load the Tk libraries first, and then spawn a new thread, the thread fails. I think maybe Tk tries to have its own thread support which conflicts with the normal use of the module, but I haven't found anything on this.

So, create all the threads you'll need ahead of time. Example:

This will spawn a thread for opening web page windows without freezing the GUI to do so:

Code:
use threads;
use threads::shared; # share some variables

# share this:
our @INPUT : shared;

# spawn a new thread
threads->create (sub {
   while (1) {
      select (undef,undef,undef,0.01); # sleep .01 seconds
      if (scalar(@INPUT)) { # if we got a message...
         # Open the webpage from @INPUT
         my $page = shift(@INPUT);
         system ("start $page");
      }
   }
})->detach;

# I always detach threads that are going to be
# running forever, because "->join" waits for
# the thread to return something. This thread
# will never return because of the while loop.

# Now we load Tk.
use Tk;

my $mw = MainWindow->new;

$mw->Button (
   -text => 'Tek-Tips',
   -command => sub {
      push (@INPUT, "[URL unfurl="true"]http://www.tek-tips.com/");[/URL]
   },
)->pack;

$mw->Button (
   -text => 'MySpace',
   -command => sub {
      push (@INPUT, "[URL unfurl="true"]http://www.myspace.com/");[/URL]
   },
)->pack;

MainLoop;

Calling system ("start web-address") will open the address in the user's default web browser. But, as with all system commands, it won't return until the command finishes. So if their computer is taking a while to open the browser, the GUI is going to be frozen until the browser shows up on their screen.

So using threads to have a separate thread open the browser windows prevents the GUI from being frozen.

This is just for concept on how to thread Tk programs. To be more efficient though, you'll want to make sure that every sub-thread shuts itself down before the main thread dies, or you'll get some last-minute warnings about "Main thread exited with 1 child process not terminated" or something along those lines.

An idea for that:
Code:
use threads;
use threads::shared;
my $children : shared;
my $shutdown : shared;

$children = 0;
$shutdown = 0;

threads->create (sub {
   $children++;

   while (1) {
      # do its stuff
      if ($shutdown) {
         $children--;
         return 1;
      }
   }
})->detach;

threads->create (sub {
   $children++;

   while (1) {
      # do its stuff
      if ($shutdown) {
         $children--;
         return 1;
      }
   }
})->detach;

threads->create (sub {
   $children++;

   while (1) {
      # do its stuff
      if ($shutdown) {
         $children--;
         return 1;
      }
   }
})->detach;

# So now we have three children, so
# $children = 3. When $shutdown = 1,
# all the children should begin returning,
# and $children = 0 when all have shut down.

# Kill the threads.
$shutdown = 1;
sleep 1 until $children == 0;
exit(0);

-------------
Kirsle.net | Kirsle's Programs and Projects
 
Kirsle,

Thanks for am extensive help.
I use just "threads",not sharing any data.However,even If I include the following line PRIOR to initializing the Tk staff,still get error...

Line:

threads->create(sub { print("I am a thread\n"); })->join();

Error:
I am a thread
Free to wrong pool 243b818 not 222770 during global destruction.


Long live king Moshiach !
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top