#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use threads;
use threads::shared;
my $go : shared;
my $die : shared;
my $step_set : shared;
my $feedback : shared;
$go = 0;
$die = 0;
$step_set = 0;
$feedback = 0;
my $repeater;
my $stepper = 0;
my $feedback_display = 0;
my $thread = threads->new(\&work);
my $mw = MainWindow->new( -title => "Stepper Test" );
my $entry = $mw->Entry(-textvariable => \$stepper)->pack();
my $indicator = $mw->Label(-textvariable => \$feedback_display)->pack(
+);
$mw->Button(-text=>'Start Stepper',
-command=> sub {
$step_set = $stepper;
$go = 1;
# timer to read shared vars
$repeater = $mw->repeat(10,sub{
$feedback_display = $feedback;
if( $feedback_display == $stepper){
$go =0;
}
});
})->pack();
$mw->Button(-text=>'Exit',
-command=> sub {
$go = 0;
$die = 1; # must return before joining
$repeater->cancel;
# JOIN ALL THREADS
foreach my $thread (threads->list) {
$thread->join;
+
}
exit;
})->pack();
MainLoop;
sub work{
$|++;
while(1){
if($die == 1){ return };
if ( $go == 1 ){
for(0..$step_set){
print "$_\n";
$feedback = $_;
select(undef,undef,undef,.5);
}
}else
{ sleep 1 }
}
}
| [reply] [d/l] |
That is excellent. Thank you! Your concise example is very fine. It's short and sweet and it runs as is on NetBSD (where I'm browsing from). Thanks very much indeed.
It's late tonight, but I'm copying it to flash memory for adapting to my Win32 program on the laptop tomorrow. Come Monday I'll try it out on the machine in question.
FYI -- My particular stepper motor application is to dial up a 20-turn needle valve in a test rig cycling pressure (ramp up, hold, ramp down) thousands of times on a jet engine fuel nozzle. Have to do it that way because this is for a contamination test. The fluid in question is JP-8 jet fuel loaded with calibrated dirt (hematite, rust, Arizona road dirt and lint) and no proportinal or servo-valve would last even 10% of the test.
| [reply] |
FINAL REPORT
It works exactly as advertized! Hurrah! My stepper motor has been running now for about 200 hours via this threads scenario.
My particular application proved a bit more complicated as the module I'd been using was OO with a number of hashes, one of them quite large. And I find that the threads module gets kind of complicated if you try to OO-ify things. Still, not to worry. Quite easily gotten around, that.
Most of that OO business was for non-stepper motor related issues: data and solenoid channels of the LabJack device. OO was by no means required for running the stepper channel as a separate consideration.
So for the stepper motor I pared things back to essentials: just the basic (non-OO) module Device::LabJack. And that part only did I put into a thread with only the absolute minimum of shared scalars.
Once simplifed in that manner it ran like a champ. The Tk GUI is lively again. Excellent suggestion. Thanks Zentara!
| [reply] |
The short answer to the title question is: You don't.
A reference is effectively the address of a piece of memory in the address space of your perl process. When you start a new process, it cannot access that piece of memory in the originating process. Even if you passed the address to the new process and it attempted to dereference it, it would either a) segfault because the new process does not have that address in it's memory space, or b) it would access a piece of memory that holds some completely unrelated value.
You could using one of the shared memory modules on CPAN, (eg. Win32::MMF ) but they tend to be fairly platform specific (ie. most don't work on win32), awkward to use and often very slow.
Alternatively, you could consider using threads. Doing a Super Search for nodes containing threads Tk should throw up a few examples of using threads with Tk. But read them carefully, there are rules that must followed for that to be successful.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
| [reply] |
Passing a "reference" between programs screams for the use of sockets (tcp, udp, unix, files, whatever) and the use of Storable for complicated structures or DB_File for simple values...
| [reply] |