Re: Multithreading
- From: muppet <scott asofyet org>
- To: Jens Wilke <jens wilke org>
- Cc: gtk-perl list <gtk-perl-list gnome org>
- Subject: Re: Multithreading
- Date: Tue, 4 Nov 2003 22:54:31 -0500
On Tuesday, November 4, 2003, at 06:51 PM, Jens Wilke wrote:
i tried to use threads, but it seems not to work together with
gtk2-perl.
Even $widget1->add($widget2); causes error.
Are there any working eyamples out there?
I want to make a whole window and all it's stuff an own thread.
I've got Image::Magick operations "in that window" which makes the
whole app
waiting.
Is there any other way in Gtk2 than forking?
Glib has a few measures taken towards thread safety: a) internal data
structures are locked, and b) closures are invoked with the interpreter
context that created them. Brett Kosinski contributed most of this, in
order to get Glib to work with his GStreamer bindings which create
processor threads in the background.
i imagine that the guidelines would be the same as with normal X apps
in C, only mess with the gui from a single thread.
/me experiments a little
yeah, it looks that way. so long as you only create widgets *after*
creating threads, it should work okay.
as i understand it:
perl's threads work by duplicating the interpreter.
that means that all existing objects are cloned when the thread is
started.
when the thread exits, the objects get cleaned up.
however, the widgets point to only one thing behind the scenes.
so when the background thread tries to clean up, it destroys the
widgets out from under the foreground thread, and badness ensues.
moral: don't do that.
(that said, we're looking into ways to keep things from blowing up if
you create widgets before launching a thread, but perl's internals can
be rather dense.)
that leaves you with the master and worker threads, communicating via
work queues and all that fun stuff. according to the manpage for
threads::shared, bless and threads don't get along, so you can't share
blessed objects, and from experience i've seen that only basic types
can be used as values in shared variables (strings, integers, doubles,
and shared references). note that Data::Dumper and eval are handy for
serializing objects into strings and thawing them out again.
-=-=-=-=-=-
use strict;
use warnings;
use threads;
use threads::shared;
my $deathflag : shared;
my @work_q : shared;
$deathflag = 0;
my $thread = threads->create (sub {
while (! $deathflag) {
if (@work_q) {
print "next: ".(shift @work_q)."\n";
sleep 1;
} else {
threads->yield;
}
}
});
use Glib;
use Gtk2 '-init';
my $lastbusy = 0;
my $n = 0;
my $win = Gtk2::Window->new;
$win->signal_connect (delete_event => sub {
if (@work_q) {
warn "can't quit, busy...\n";
} else {
Gtk2->main_quit;
$deathflag = 1;
}
# either way, don't destroy the window -- we'll do that
# by hand below.
return 1;
});
my $box = Gtk2::VBox->new;
$win->add ($box);
my $label = Gtk2::Label->new ('idle');
$box->add ($label);
my $button = Gtk2::Button->new ('queue some work');
$box->add ($button);
$button->signal_connect (clicked => sub {
push @work_q, ++$n;
});
Glib::Idle->add (sub {
# touch the queue only once to avoid race conditions.
my $thisbusy = @work_q;
if ($thisbusy != $lastbusy) {
$label->set_text ($thisbusy ? "$thisbusy left" : 'idle');
$lastbusy = $thisbusy;
}
1;
});
$win->show_all;
Gtk2->main;
$win->destroy;
$thread->join;
--
muppet <scott at asofyet dot org>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]