Re: Threading question, bug or coding problem?



On Wed, 12 Dec 2007 09:33:25 -0500 (EST)
"Bryan Bueter" <bryan bueterfamily org> wrote:

I'm trying to write an application that kicks off several threads to do
things not related to Gtk, and Gtk/Glib seems to be having trouble.  So my
question is whether its a bug in the immature threading model for perl, or
something that I'm not doing correctly.

My program does this: creates a gtk gui, then defines an action to kick
off several threads and monitors them updating a progress bar, pretty
standard stuff.  However, if i thread once it seemingly works no problems,
if i go back and thread again Glib complains and hozes up the gui.

Here is sample code that demonstrates the problem:

--- snip ---
BB

Hi,

I'm sorry to say, that it seems as though your code should work, but it won't.
It's just that the memory cleanup is not that good yet.  So your thinking is solid.
Everyone dabbling in threads with perl runs into this.  Threads with Tk is even
worse, at least Gtk2 is attempting(with some success) at thread safety. At least
in Gtk2, with g_idle_add, you can access Gtk2 widgets from threads. But that is
Chapter 2 of Gtk2/threads. :-)


Back to Chapter1 .........
Muppet may know a way, but I've hacked and hacked, and have yet to find
a way in Gtk2 to spawn the threads AFTER the gui is up and running, and NOT
get problems. It may seem to work, then suddenly an error pops up.

You can probably get your script to work by detaching your threads instead of joining,
but you will gain memory with every button press, as a complete copy of the
process is made to start new threads.

The only way to get real solid thread use, is to pre-create your threads, before
any Gtk2 code is invoked, put them in a sleep loop, and wake them up with shared
variables, and reuse them.  This way, they are created without any gui code present.
It's harder to do, but it's very solid, an example is at
 http://perlmonks.org?node_id=470661 

Now, always watch your memory gains with threads. The above link has a script
that is stable with memory, it pre-creates the threads, and reuses them.  It will 
run all day in my testing.  You can even pass code strings to be eval'd in the thread,
thru shared variables.

Now to GLib, one level lower in the object heirarchy.
If you can just use a command line app, look at the following.
Below, is the closest I've come using just GLib( and no gui ), to dynamically
spawn threads.  Just hit Enter once or multiple times, to spawn dynamic
threads , without accumulating memory. Of course, the total Perl memory
will rise to the peak level, and won't give it back. But if you just start 3 at a time,
let them finish, then start another 3, no memory gain will be seen.

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;
use Glib;
use Glib qw/TRUE FALSE/;
$|++;

#Glib::Object->set_threadsafe (TRUE);  # will cause error if used

my $main_loop = Glib::MainLoop->new;

Glib::IO->add_watch (fileno 'STDIN', [qw/in/], \&watch_callback);       

$main_loop->run;

######################################

sub watch_callback {
  while (<>) {                                                                        
    my $line = $_;
    if (defined($line) and $line ne ''){
          print $line;
          start_it();
    }
  }
return 0;
}

sub start_it{
      my $thread = threads->new(\&start_thread)->detach;
 }

sub start_thread {

   my $self = threads->self;
   my  $num ||= $self->tid;
   print "Thread ", $self->tid, " started\n";
   print "idenitifier: $num\n"; 

    for(1..10){
         print '  ' x $num, 'ZZ',"\n";  
           select(undef,undef,undef,.1);
    }

print "thread $num terminating\n";

}
__END__


Good Luck,
zentara


-- 
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]