Jez,

For a "rough" answer, that was very useful and interesting! These little
demo scripts are a goldmine of information. I have been using threads to
carry out background work while updating a progress bar in the main window
and providing a cancel button. It will be interesting to see Rob's
inter-thread communication code when it's ready.

One thing I noticed in my program, that also occurs when I run your example,
is that I get a message complaining that "A thread exited while 6 threads
were running" if the main window is exited first. I thought the detach()
method was supposed to prevent that. I seem to remember that when you
actually do a join(), as suggested in the documentation, there are other
problems. Do you also see this? Do you know what is going wrong?

Glenn

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of
Jeremy White
Sent: Friday, 30 December, 2005 08:16
To: [EMAIL PROTECTED]; [EMAIL PROTECTED];
perl-win32-gui-users@lists.sourceforge.net
Subject: RE: [perl-win32-gui-users] PerlApp issue


>For the Win32::GUI guirus (spelling intended:-)), is Win32::GUI thread 
>safe?

I'm not a guru, but if you want a rough answer:

Yes, Win32::GUI is thread safe. Well, sort off:) Rob May and I have had an 
exchange of emails about how to make Win32::GUI thread programming easier, 
after some testing we came up with some interesting results.

The first thing to mention is that the main limiting factor is perl itself. 
Only the 5.8.x codeline is worth considering, with the latest version 
(5.8.7) being the best to use.

The core of Win32::GUI is indeed thread safe - all the XS/C code - (well, we

have yet to find an issue). Rob found that a couple of lines of perl code is

needed within Win32-GUI to make itself fully thread safe. This can be 
achieved with the following code:

use strict;
use warnings;
use 5.007002; # Perl 5.7.2 or higher needed for CLONE_SKIP
use threads;
use threads::shared;

use Win32::GUI();

# make Win32::GUI threadsafe
sub Win32::GUI::CLONE_SKIP {1};
sub Win32::GUI::Timer::CLONE_SKIP {1};

The CLONE_SKIP function would need to be added for all Win32-GUI objects 
that you would use. New versions of Win32-GUI would have these functions 
already added.

Win32-GUI is surprising robust with threading, as each spawned thread can 
create it's own windows, with the creating thread responding to events for 
that window. The major limitation is that you can't change the thread that 
handles the event for a window. For example, if thread A creates a window, 
you can't make thread B respond to events for that window. With this 
limitation in mind, you can do things like:

#!perl -w
$|=1;
use strict;
use warnings;

use 5.007_002; # Perl 5.7.2 or higher needed for CLONE_SKIP
use threads;

use Win32::GUI();

# Make Win32::GUI thread-safe
sub Win32::GUI::CLONE_SKIP {1};
my $count=1;
my $numberOfWorkers=5;

my $main=MainWindow('main',$count++);

my $thr;
for (1..$numberOfWorkers) {
  $thr = threads->create(\&Worker2,"worker $_",$count++);
  $thr->detach();
}
$main->Show();
Win32::GUI::Dialog();


sub MainWindow {
  my ($name, $number)[EMAIL PROTECTED];
  my $mw = Win32::GUI::Window->new(
        -title => "$name thread window",
        -pos   => [400,400],
        -size  => [300,200],
  );

  $mw->AddTextfield (
    -name   => 'Log',
    -height => 80,
    -width  => 160,
    -top    => 4,
    -left   => 4,
    -multiline => 1,
    -addstyle => 2097152,
    -addstyle=>4096,

  );
  return $mw;
}

sub Worker2 {
  my ($name, $number)[EMAIL PROTECTED];


  my $mw = Win32::GUI::Window->new(
        -title => "$name thread window",
        -pos   => [100,100],
        -size  => [300,200],
  );

  $mw->AddButton(
        -text => 'Do some work in this window',
        -pos  => [114, 10],
        -height => 20,
        -onClick => \&Job,
  );

  $mw->AddTextfield (
    -name   => 'Process',
    -height => 20,
    -width  => 35,
    -top    => 2,
    -left   => 20,
  );

  $mw->Process->Text($number);
  $mw->Show();
  #the thread enters the Dialog phase
  Win32::GUI::Dialog();
}

sub Job {
  my $self=shift;
  my $parent=$self->GetParent();
  my $id=threads->tid();
  #do some work for 2 seconds
  Win32::Sleep(2000);
  my $item=$parent->Process->Text();
  print "finished $item in thread $id";
}

Which creates 6 windows, each one running in it's own thread. You'll need 
the latest version of Win32-GUI to run this example.

Rob May has developed some very interesting code that will make the 
communication between threads that use Win32-GUI objects so easy to do, that

we'll all be building threading win32-gui apps in our sleep:)

Cheers,

jez.




-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
http://perl-win32-gui.sourceforge.net/


Reply via email to