RE: [perl-win32-gui-users] Multi-Threaded Example
Actually it was a mistake, thanks for sending it! I was starting to wonder where the blazes it went! Yes that restriction might be a bit of an issue, however I *suppose* information on the control (not the control itself) could be serialized and sent over a Queue to the process altering the control. I have yet to test this. Be Careful. Jason P. -Original Message- From: Emmanuel E [mailto:[EMAIL PROTECTED] Sent: Friday, February 03, 2006 11:51 PM To: Plum, Jason Subject: Re: [perl-win32-gui-users] Multi-Threaded Example I guess you cracked it! This one works great. I was getting those "Free to wrong pool errors" till I moved the thread exit and join code to the Win_Terminate sub. But that resulted in "Scalars leaked". Wonder whether the constraint of "will need to know what type of control that handle relates to." will create problems in trying to create neatly packaged objects. Btw did you not intend to send this to the list? I felt it is good enough to be archived forever! Cheers, Emmanuel - Original Message - From: "Plum, Jason" <[EMAIL PROTECTED]> To: "Emmanuel E" <[EMAIL PROTECTED]> Sent: Saturday, February 04, 2006 12:48 AM Subject: RE: [perl-win32-gui-users] Multi-Threaded Example AH.. now then... So.. the bug involving the object being in multiple threads does indeed still exist! "Free to wrong Pool not in %perl%/site/lib/win32/gui.pm" The module itself is not thread safe in relation to objects! BUT! BUT! By using the *HANDLE* to the object, you can call the relative procedure directly! Search for [EMAIL PROTECTED] for alterations. This leaves the obvious requirement that any code that is going to directly alter the state of a control will need to know what type of control that handle relates to. Jason P. -Original Message- From: Emmanuel E [mailto:[EMAIL PROTECTED] Sent: Friday, February 03, 2006 1:49 PM To: Plum, Jason; perl-win32-gui-users@lists.sourceforge.net Subject: Re: [perl-win32-gui-users] Multi-Threaded Example Hi Jason, Cool stuff! But would there be a way to avoid those select calls to spend some time sleeping? I mean if there were a way to do a select on a thread queue it would be great. On the other hand why not call Win32::GUI::Dialog() in the main thread and let the child threads update the screen? I mean move this line to within the child threads: $win->{pbT1}->SetPos($t1_in); and $win->{pbT2}->SetPos($t2_in); ? If you move the create window code before you create any threads all child threads will inherit the window. I've made a few modifications to your script - 1) Ive disabled the queue, implying shared globals as one way of passing data to and fro from threads. With the queue gone theres nothing to do in the event loop but update the screen using Win32::GUI::Dialog(); 2) Ive moved the thread join code into the Window_Terminate sub However I get the following message when the script exits: Scalars leaked: 1 Scalars leaked: 1 Wonder what thats related to? Am attaching the code to avoid syntax errors because of word wraps. Cheers, Emmanuel - Original Message - From: "Plum, Jason" <[EMAIL PROTECTED]> To: Sent: Friday, February 03, 2006 9:25 PM Subject: [perl-win32-gui-users] Multi-Threaded Example Hey All, I was fiddling with some things yesterday and got around to wondering how I might manage to take some of my more heavy duty linear processes run in a thread outside of the thread containing the GUI (as we all know this causes ugly interface lag). Below is an example, and as with all things perl, this is not the only way to do it, nor is it necessarily the best way to do it. Consider it a proof of concept that functions. This creates worker threads that put values 0-99 consecutively onto a Queue whiles the function's 'run' semaphore is positive. It also contains a run-away limiter to prevent the workers from getting too far ahead of the main thread, containing the window. Jason P. __CODE__ use strict; use warnings; use threads; use threads::shared; use Thread::Queue; ## Create worker threads and associated variables. ## -- THIS MUST BE DONE, AND ALL THREADS STARTED ## -- BEFORE THE WINDOW IS CREATED. my $TQ1 = new Thread::Queue; my $TQ2 = new Thread::Queue; my $ts1_run : shared = 0; my $ts2_run : shared = 0; my $thread1 = threads->new(\&Thread1); my $thread2 = threads->new(\&Thread2); use Win32::GUI; ## Hide Perl Window my $perlW = Win32::GUI::GetPerlWindow(); Win32::GUI::Hide($perlW); ## Create Window my $win = new Win32::GUI::Window( -name => 'winMain', -size => [200,100], -pos => [200,200], -caption => 'MutliThread E.g.', -resizeable => 0, ); $win->AddButton( -name => 'btnRun1', -size => [50,20], -pos=> [4,10], -text => 'Run 1', ); $win->AddProgressBar( -name => 'pbT1', -size => [120,20], -pos=> [58,10], -smooth => 1, ); $win->{pbT1}->SetRange(0
RE: [perl-win32-gui-users] Multi-Threaded Example
Actually it was a mistake, thanks for sending it! I was starting to wonder where the blazes it went! Yes that restriction might be a bit of an issue, however I *suppose* information on the control (not the control itself) could be serialized and sent over a Queue to the process altering the control. I have yet to test this. Be Careful. A few months back I hinted at some code that Rob had built that would make threading coding much easier for Win32-GUI apps. In light of your recent examples, I've dropped him an offlist mail suggesting that his code be available to more people. Although not complete, it is a great platform to build from. One of the problems that Rob's code solves is that one end of a thread message queue can be attached to a window meaning there are no sleeps or polling to check for new messages. Basically, it means that a working thread can fire events in the thread controlling the window, resulting in a very efficient and simple event driven threading model. Cheers, jez.
RE: [perl-win32-gui-users] Multi-Threaded Example
Resend of missed message. Actually it was a mistake, thanks for sending it! I was starting to wonder where the blazes it went! Sorry Jason, I didnt send your message to the list. Doing it now. In case someone might want to take a look at re_threaded_exampl.pl - Original Message - From: "Plum, Jason" <[EMAIL PROTECTED]> To: "Emmanuel E" <[EMAIL PROTECTED]> Sent: Saturday, February 04, 2006 12:48 AM Subject: RE: [perl-win32-gui-users] Multi-Threaded Example AH.. now then... So.. the bug involving the object being in multiple threads does indeed still exist! "Free to wrong Pool not in %perl%/site/lib/win32/gui.pm" The module itself is not thread safe in relation to objects! BUT! BUT! By using the *HANDLE* to the object, you can call the relative procedure directly! Search for [EMAIL PROTECTED] for alterations. This leaves the obvious requirement that any code that is going to directly alter the state of a control will need to know what type of control that handle relates to. Jason P. -Original Message- From: Emmanuel E [mailto:[EMAIL PROTECTED] Sent: Friday, February 03, 2006 1:49 PM To: Plum, Jason; perl-win32-gui-users@lists.sourceforge.net Subject: Re: [perl-win32-gui-users] Multi-Threaded Example Hi Jason, Cool stuff! But would there be a way to avoid those select calls to spend some time sleeping? I mean if there were a way to do a select on a thread queue it would be great. On the other hand why not call Win32::GUI::Dialog() in the main thread and let the child threads update the screen? I mean move this line to within the child threads: $win->{pbT1}->SetPos($t1_in); and $win->{pbT2}->SetPos($t2_in); ? If you move the create window code before you create any threads all child threads will inherit the window. I've made a few modifications to your script - 1) Ive disabled the queue, implying shared globals as one way of passing data to and fro from threads. With the queue gone theres nothing to do in the event loop but update the screen using Win32::GUI::Dialog(); 2) Ive moved the thread join code into the Window_Terminate sub However I get the following message when the script exits: Scalars leaked: 1 Scalars leaked: 1 Wonder what thats related to? Am attaching the code to avoid syntax errors because of word wraps. Cheers, Emmanuel - Original Message - From: "Plum, Jason" <[EMAIL PROTECTED]> To: Sent: Friday, February 03, 2006 9:25 PM Subject: [perl-win32-gui-users] Multi-Threaded Example Hey All, I was fiddling with some things yesterday and got around to wondering how I might manage to take some of my more heavy duty linear processes run in a thread outside of the thread containing the GUI (as we all know this causes ugly interface lag). Below is an example, and as with all things perl, this is not the only way to do it, nor is it necessarily the best way to do it. Consider it a proof of concept that functions. This creates worker threads that put values 0-99 consecutively onto a Queue whiles the function's 'run' semaphore is positive. It also contains a run-away limiter to prevent the workers from getting too far ahead of the main thread, containing the window. Jason P. __CODE__ use strict; use warnings; use threads; use threads::shared; use Thread::Queue; ## Create worker threads and associated variables. ## -- THIS MUST BE DONE, AND ALL THREADS STARTED ## -- BEFORE THE WINDOW IS CREATED. my $TQ1 = new Thread::Queue; my $TQ2 = new Thread::Queue; my $ts1_run : shared = 0; my $ts2_run : shared = 0; my $thread1 = threads->new(\&Thread1); my $thread2 = threads->new(\&Thread2); use Win32::GUI; ## Hide Perl Window my $perlW = Win32::GUI::GetPerlWindow(); Win32::GUI::Hide($perlW); ## Create Window my $win = new Win32::GUI::Window( -name => 'winMain', -size => [200,100], -pos => [200,200], -caption => 'MutliThread E.g.', -resizeable => 0, ); $win->AddButton( -name => 'btnRun1', -size => [50,20], -pos=> [4,10], -text => 'Run 1', ); $win->AddProgressBar( -name => 'pbT1', -size => [120,20], -pos=> [58,10], -smooth => 1, ); $win->{pbT1}->SetRange(0,99); $win->AddButton( -name => 'btnRun2', -size => [50,20], -pos=> [4,32], -text => 'Run 2', ); $win->AddProgressBar( -name => 'pbT2', -size => [120,20], -pos=> [58,32], -smooth => 1, ); $win->{pbT2}->SetRange(0,99); $win->Show(); my $run = 1; # Home rolled w/ DoEvents. while($run){ # get inputs. my $t1_in = $TQ1->dequeue_nb(); if( defined $t1_in ){ $win->{pbT1}->SetPos($t1_in); #print "Get T1 $t1_in\n"; $ts1_run++; } my $t2_in = $TQ2->dequeue_nb(); if( defined $t2_in ){ $win->{pbT2}->SetPos($t2_in); #print "Get T2 $t2_in\n"; $ts2_run++; } $win->DoEvents(); select(undef, undef, undef, 0.01); # take a 1/100s break to no
RE: [perl-win32-gui-users] Multi-Threaded Example
This is actually rather simple. Simple create a shared variable containing the a scalar handle to the window, and proceed to "Win32::GUI::SendMessage($ts_winHandle, WM_USER +2)" etc., thus allowing for no need to actually poll the Queue for status, as the message stack for the window will *tell* when there is an item in the Queue... Sorry I didn't include that in the example, as it was dated from before the weekend and I haven't been to this email account since then even though I have been working on the ideas in my spare time at home. Jason P. See Attached. -Original Message- From: Jeremy White [mailto:[EMAIL PROTECTED] Sent: Monday, February 06, 2006 12:04 PM To: Plum, Jason; perl-win32-gui-users@lists.sourceforge.net Subject: RE: [perl-win32-gui-users] Multi-Threaded Example >Actually it was a mistake, thanks for sending it! I was starting to >wonder where the blazes it went! > >Yes that restriction might be a bit of an issue, however I *suppose* >information on the control (not the control itself) could be serialized >and sent over a Queue to the process altering the control. I have yet to >test this. Be Careful. A few months back I hinted at some code that Rob had built that would make threading coding much easier for Win32-GUI apps. In light of your recent examples, I've dropped him an offlist mail suggesting that his code be available to more people. Although not complete, it is a great platform to build from. One of the problems that Rob's code solves is that one end of a thread message queue can be attached to a window meaning there are no sleeps or polling to check for new messages. Basically, it means that a working thread can fire events in the thread controlling the window, resulting in a very efficient and simple event driven threading model. Cheers, jez. mt-eg-3.pl Description: mt-eg-3.pl