Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Problems understanding and implementing process management

Reply
Thread Tools

Problems understanding and implementing process management

 
 
James Calivar
Guest
Posts: n/a
 
      07-08-2005
Hello,

I'm a pretty new Perl programmer, and am having some difficulty in finding
the correct way to approach process management in an application that I'm
writing. Basically, I've written a Perl/Tk script that pops up a nice GUI
that a user can use to configure some parameters, and then press a Start
button to kick off a separate (already written and tested) Perl script.
This secondary Perl script is something that I want to have run as a
separate process from the GUI script, and it does its own thing in the
background. I want to be able to terminate the secondary script at any time
by pressing a Stop button, with the result that the secondary process is
terminated but the GUI remains up so that the process can be kicked off
again is desired.

I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).

Now, I've been somewhat successful in invoking the secondary script by using
one of a couple of different methods. But I'm not sure which one is really
appropriate for my application. The first thing I did was to just try to
use the system() command - but this waits for the secondary process to
terminate before the GUI proceeds, the net effect being that when I press
the Start button, the GUI essentially hangs up (with the button depressed)
and only recovers after I kill the secondary script with Ctrl-C. (I do not
want to use the exec() function, because that terminates the GUI.) I also
tried using fork(), but every time I invoke it, the script crashes and gives
me the "Windows has encoutered a problem - would you like to file a report?"
error message. So it seems that fork() is out. Finally, I tried using
piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
Filehandles"). That also kicks off my secondary script, and returns control
over the GUI to me, but now I cannot terminate the secondary process. And I
believe it's because, as with the system() call, the close command issued to
the filehandle that I have assigned to the secondary process also has to
wait for that process to terminate, which it won't - so again, I'm stuck.

Can anyone here kindly nudge me in the right direction? Am I on the right
track, or do I need to switch methods altogether? I can provide code
examples if need be.

Thanks

James


 
Reply With Quote
 
 
 
 
Ala Qumsieh
Guest
Posts: n/a
 
      07-08-2005
James Calivar wrote:

> Hello,
>
> I'm a pretty new Perl programmer, and am having some difficulty in finding
> the correct way to approach process management in an application that I'm
> writing. Basically, I've written a Perl/Tk script that pops up a nice GUI


What GUI library are you using? If Tk, then perhaps you can use the
Tk::fileevent method, as described in its pods.

> that a user can use to configure some parameters, and then press a Start
> button to kick off a separate (already written and tested) Perl script.


What does the second script do? Is there any data that needs to be
passed back to the GUI?

> I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).
>
> Now, I've been somewhat successful in invoking the secondary script by using
> one of a couple of different methods. But I'm not sure which one is really
> appropriate for my application. The first thing I did was to just try to
> use the system() command - but this waits for the secondary process to
> terminate before the GUI proceeds, the net effect being that when I press
> the Start button, the GUI essentially hangs up (with the button depressed)
> and only recovers after I kill the secondary script with Ctrl-C. (I do not


I believe on Windows, you can use the command "start prog.pl" to run
your second Perl script in the background.

> want to use the exec() function, because that terminates the GUI.) I also
> tried using fork(), but every time I invoke it, the script crashes and gives
> me the "Windows has encoutered a problem - would you like to file a report?"
> error message. So it seems that fork() is out. Finally, I tried using


The perlfork pods claim:

On some platforms such as Windows where the fork() system call is not
available, Perl can be built to emulate fork() at the interpreter
level.

Which Win32 Perl distribution are you using?

> piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
> Filehandles"). That also kicks off my secondary script, and returns control
> over the GUI to me, but now I cannot terminate the secondary process. And I


Can you show this code?

If you use open() to create your pipe, then the return value of your
open is the pid of your child process. You can use that to kill() it.

--Ala

 
Reply With Quote
 
 
 
 
James Calivar
Guest
Posts: n/a
 
      07-08-2005
"Ala Qumsieh" <(E-Mail Removed)> wrote in message
news:hWyze.3188$6%(E-Mail Removed). ..
> James Calivar wrote:
>
> > Hello,
> >
> > I'm a pretty new Perl programmer, and am having some difficulty in

finding
> > the correct way to approach process management in an application that

I'm
> > writing. Basically, I've written a Perl/Tk script that pops up a nice

GUI
>
> What GUI library are you using? If Tk, then perhaps you can use the
> Tk::fileevent method, as described in its pods.
>


Tk is what I'm using. The GUI part is all done; it's just this last one
command that kicks off another process that is driving me nuts.

> > that a user can use to configure some parameters, and then press a Start
> > button to kick off a separate (already written and tested) Perl script.

>
> What does the second script do? Is there any data that needs to be
> passed back to the GUI?
>


Well, in the *real* application, the secondary script does a lot of stuff.
But as far as the calling GUI code is concerned, it does nothing - it just
goes out and stays out and needs to be killed off at some point via some
method yet to be determined. So, for the purposes of testing, I've just
replaced it with a script that prints out the "spinning text wheel" either
for 30 seconds or so, or (optionally if I uncomment out the commented
lines), forever. This kind of emulates a long-lived process. And since it
won't ever return/terminate (at least not immediately), I can't use
system(), exec() or the "piped process" method since all of those methods
must wait for the secondary application's termination before they can
proceed.

> > I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).
> >
> > Now, I've been somewhat successful in invoking the secondary script by

using
> > one of a couple of different methods. But I'm not sure which one is

really
> > appropriate for my application. The first thing I did was to just try

to
> > use the system() command - but this waits for the secondary process to
> > terminate before the GUI proceeds, the net effect being that when I

press
> > the Start button, the GUI essentially hangs up (with the button

depressed)
> > and only recovers after I kill the secondary script with Ctrl-C. (I do

not
>
> I believe on Windows, you can use the command "start prog.pl" to run
> your second Perl script in the background.
>


Do you mean system()?

> > want to use the exec() function, because that terminates the GUI.) I

also
> > tried using fork(), but every time I invoke it, the script crashes and

gives
> > me the "Windows has encoutered a problem - would you like to file a

report?"
> > error message. So it seems that fork() is out. Finally, I tried using

>
> The perlfork pods claim:
>
> On some platforms such as Windows where the fork() system call is not
> available, Perl can be built to emulate fork() at the interpreter
> level.
>
> Which Win32 Perl distribution are you using?


Win XP Pro, running Perl ActiveState Perl 5.8.7 (Build 813) - I just
upgraded.

>
> > piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
> > Filehandles"). That also kicks off my secondary script, and returns

control
> > over the GUI to me, but now I cannot terminate the secondary process.

And I
>
> Can you show this code?
>
> If you use open() to create your pipe, then the return value of your
> open is the pid of your child process. You can use that to kill() it.
>
> --Ala
>


Here is the code, stripped down somewhat so that noone has to look at all
the meaningless parts. There are two files: daemon_gui.pl, and test2.pl.
daemon_gui.pl is the Tk-enabled "master" code that sets up the GUI
environment, and kicks off the secondary file (test2.pl) when the "Start
Daemon" button is pressed. As you can see, test2.pl is simply a stub that
"spins its wheels" in the command-line window that daemon_gui.pl is invoked
from (I always like to start the script from a CLI when developing, because
then I can see messages that I would lose if I just double-clicked the file
in Windows Explorer).

So basically, if you invoke daemon_gui.pl (from CLI), the click the Start
button, you'll see the "spinning text" in the CLI. Now what I *want* to
happen is when I press Stop, the secondary script is terminated immediately.
But what is *actually* happening is that the Stop button's actions do not go
into effect until the secondary script has stopped processing.

Some rudimentary debug code in daemon_gui.pl (lines 118 and 129) show me
that the process ID that I am attempting to kill is the same one created
when I invoke the secondary script. Do I need to embed a signal handler
routine in the secondary script or something?

Any ideas, comments, questions, etc?

Thanks for your help

James Calivar

daemon_gui.txt:
==========
#---------------------------#
# initial environment setup
#---------------------------#
use Tk;
use Tk::widgets qw/Dialog/;
use Tk::Balloon;
use subs qw/buildMenuBar finishUp startDaemon stopDaemon/;
use vars qw/$MW $VERSION $pid/;
use strict;

################################################## ##########################
##############
# BEGIN Variable Declarations
#---------------------------------------------------------------------------
-------------#

# version number for internal tracking
$VERSION = '0.97';

#-----------------------------------------------#
# hash used to hold values for all config params
#-----------------------------------------------#
my %config = (
"dbpwd" => undef
);

my @hash_keys = keys %config;
my @hash_vals = values %config;

#-----------------------------------------------#
# hash used to hold popup balloon text msgs
#-----------------------------------------------#
my %configMessages = (
"dbpwd" => "Password for database user account (hidden when typed on
screen)"
);

#-----------------------------------------------#
# hash used to hold handles to Entry widgets
#-----------------------------------------------#
my %configEntry;

#---------------------------------------------------------------------------
-------------#
# END Declarations
################################################## ##########################
##############

################################################## ##########################
##############
# BEGIN Main window geometry setup
#---------------------------------------------------------------------------
-------------#

#-------------------------------------#
# define the main window's attributes
#-------------------------------------#
$MW = MainWindow->new;
$MW->geometry("520x540+0+0");
$MW->title("Daemon GUI $VERSION");
my $menubar = buildMenuBar;

#-------------------------------------------------#
# set up conf.ini variable labels and entry boxes
#-------------------------------------------------#
my $startButton = $MW->Button (-text => "Start Daemon\n", -anchor => 'n',
-foreground => 'black',
-background => 'SeaGreen3',
-activeforeground => 'black',
-activebackground => 'green',
-command => sub {startDaemon})
->place(-anchor=>'nw', -x=>325, -y=>467);

my $stopButton = $MW->Button (-text => "Stop Daemon\n", -anchor => 'n',
-foreground => 'black',
-background => 'salmon1',
-activeforeground => 'white',
-activebackground => 'red',
-command => sub {stopDaemon})
->place(-anchor=>'nw', -x=>425, -y=>467);

my $idx = 0;
foreach my $key (@hash_keys)
{
# draw a label widget that annotates the variable being entered
my $label = $MW->Label(-text => "$key:\n")->place(-anchor =>
'nw', -x=>0, -y=>(10 + $idx*25));

# draw a popover balloon that describes the label widget
my $balloon = $MW->Balloon(-state => 'balloon');
$balloon->attach($label, -balloonmsg => $configMessages{$key}, -initwait
=> 10,
-balloonposition => 'mouse', -state => 'balloon');

# draw an entry widget that accepts input for the variable being entered
# special case for password, which should show up as asteriks
if ($key eq 'dbpwd')
{
$configEntry{$key} = $MW->Entry(-textvariable => \$config{$key}, -show
=> '*')
->place(-anchor=>'nw', -x=>150, -y=>(1
0 + $idx*25));
}
else
{
$configEntry{$key} = $MW->Entry(-textvariable => \$config{$key})
->place(-anchor=>'nw', -x=>150, -y=>(1
0 + $idx*25));
}
$idx++;
}

#---------------------------------------------------------------------------
-------------#
# END Main window geometry setup
################################################## ##########################
##############

################################################## ##########################
##############
# BEGIN Subroutine Definitions
#---------------------------------------------------------------------------
-------------#

#--------------------------------------#
# Start the daemon if all config values
# have been filled out; look for config
# file first, then check entries in GUI
#--------------------------------------#
sub startDaemon {

# kick off daemon
$pid = open DAEMON, "|perl test2.pl";
print ("Process ID created is $pid\n");

} # end startDaemon()

#--------------------------------------#
# commit the changes to the conf file
# (this will be a lot cleaner with the
# config hash)
#--------------------------------------#
sub stopDaemon {

print ("Process ID to kill is $pid\n");
kill 2, $pid or die "Cannot signal $pid with SIGINT: $!";
close DAEMON;

} # end stopDaemon()

#---------------------------------#
# build up the GUI's menu structure
#---------------------------------#
sub buildMenuBar {

# Create the menubar, and File and Quit menubuttons. Note
# that the cascade's menu widget is automatically created.
my $menubar = $MW->Menu;
$MW->configure(-menu => $menubar);
my $file = $menubar->cascade(-label => '~File', -tearoff => 0);
my $help = $menubar->cascade(-label => '~Help', -tearoff => 0);

# Create the menuitems for each menu. First, the File menu item.
$file->command(-label => "Open...", -command => \&open);
$file->separator;
$file->command(-label => "Save...", -command => \&save);
$file->separator;
$file->command(-label => "Quit", -command => \&finishUp);

# Help menuitems (Version and About)
$help->command(-label => 'Version');
$help->separator;
$help->command(-label => 'About');

my $ver_dialog = $MW->Dialog(-title => 'Daemon GUI Utility',
-font=> "Arial 10 normal",
-text=> "Daemon GUI Utility Version
$VERSION",
-buttons => ['OK'],
-bitmap => 'info');

my $about_dialog = $MW->Dialog(-title => 'About Daemon GUI Utility',
-font=> "Arial 10 normal",
-text=> "Daemon GUI Utility Version
$VERSION\n\n\Copywright 2005\n\nDaemon GUI Enterprises, Inc. (LLC)\n\nUse
without explicit permission is strictly prohibited. Violators will be
prosecuted to the fullest extent of the law.",
-buttons => ['OK']);

my $menu = $help->cget('-menu');
$menu->entryconfigure('Version', -command => [$ver_dialog => 'Show']);
$menu->entryconfigure('About', -command => [$about_dialog => 'Show']);

# return the menubar
$menubar;

} # end buildMenuBar()

#--------------------------------------------------#
# retrieve GUI configuration from earlier sessions
#--------------------------------------------------#
sub open {

} # end open()

#--------------------------------------#
# save GUI configuration for later use
#--------------------------------------#
sub save {

} # end save()

#-------------------------------#
# Clean up and exit the program
#-------------------------------#
sub finishUp {

exit;

} # end finishUp()

#---------------------------------------------------------------------------
-------------#
# END Subroutine Definitions
################################################## ##########################
##############

################################################## ##########################
##############
# BEGIN Main Event Processor Loop
#---------------------------------------------------------------------------
-------------#

MainLoop;

#---------------------------------------------------------------------------
-------------#
# END Main Event Processor Loop
################################################## ##########################
##############

test2.pl:
=====
use strict;

my $i = 0;
# while (1) {
for ($i = 0; $i <= 2000000; $i++) {
if (($i % 4) == 0) {
print "|\r";
} elsif (($i % 4) == 1) {
print "/\r";
} elsif (($i % 4) == 2) {
print "-\r";
} else {
# $i = 0;
print "\\\r";
}
# $i++;
}


 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-08-2005
"James Calivar" <(E-Mail Removed)> wrote in
news:damkjv$k5k$(E-Mail Removed):

> Here is the code,


Please make an effort not to use extra comment lines that wrap when
pasted, and format you source code nicely. Consider running it through a
code beautifier even if you are not willing to follow the recommendations
given in perldoc perlstyle.

I have been trying to run your code for the last 15 minutes, but it won't
due to various problems.

Sinan
--
A. Sinan Unur <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html
 
Reply With Quote
 
Ala Qumsieh
Guest
Posts: n/a
 
      07-08-2005
James Calivar wrote:
> "Ala Qumsieh" <(E-Mail Removed)> wrote in message
>
>>What GUI library are you using? If Tk, then perhaps you can use the
>>Tk::fileevent method, as described in its pods.

>
> Tk is what I'm using. The GUI part is all done; it's just this last one
> command that kicks off another process that is driving me nuts.


Ok, I can suggest two ways to proceed:

1. Use Tk::fileevent. I have done exactly the same thing before, but
it's a bit tedious since you have to keep track of many things.

2. Use Tk::ExecuteCommand (available from CPAN) that is just a nice
wrapper around Tk::fileevent that allows you to do cool things like:

$ec = $mw->ExecuteCommand(...)->pack;
$ec->execute_command;
$ec->kill_command;

I would go with #2.

--Ala
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-09-2005
James Calivar <(E-Mail Removed)> wrote in
news:hZIze.19925$(E-Mail Removed) link.net:

> A. Sinan Unur wrote:
>> "James Calivar" <(E-Mail Removed)> wrote in
>> news:damkjv$k5k$(E-Mail Removed):
>>
>>
>>>Here is the code,

>>
>>
>> Please make an effort not to use extra comment lines that wrap when
>> pasted, and format you source code nicely. Consider running it
>> through a code beautifier even if you are not willing to follow the
>> recommendations given in perldoc perlstyle.
>>

>
> OK - did I exceed some magic column number?


I am not sure if it is magic, but I hope you can see the problem with

#-----------------------------------------------------------------------
-----------------#

which is 90 characters wide.

> What is a code beautifier?


See, for example, <URL:http://perltidy.sourceforge.net/>

>> I have been trying to run your code for the last 15 minutes, but it
>> won't due to various problems.

....
> Can you tell me what are the "various problems"?


Well, when you have lines like the one above, perl does not just say,
oh, the line was too long, it just spilled over to the next line, and
created some weird thing. It says:

Number found where operator expected at D:\Home\gui.pl line
102, near "0"
(Missing semicolon on previous line?)
Number found where operator expected at D:\Home\gui.pl line
108, near "0"
(Missing semicolon on previous line?)
Can't modify negation (-) in predecrement (--) at D:\Home\gui.pl line
18, near "$VERSION ="
syntax error at D:\Home\gui.pl line 102, near "0"
syntax error at D:\Home\gui.pl line 108, near "0"
syntax error at D:\Home\gui.pl line 130, near "sub startDaem
on "
syntax error at D:\Home\gui.pl line 136, near "}"
Execution of D:\Home\gui.pl aborted due to compilation errors.

Then, it is not clear at first sight, what is causing these problems.
Then, after some time, I realized the long, vanity comments. At that
point, I had no more motivation to try anything.

I am glad Ala was able to help you (and I learned something from his
post). But the next time, I won't even see your post.

Sinan

--
A. Sinan Unur <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      07-09-2005
James Calivar <(E-Mail Removed)> wrote:


> I'm a pretty new Perl programmer,



I'm a ugly old Perl programmer.


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Joe Smith
Guest
Posts: n/a
 
      07-10-2005
James Calivar wrote:
> because I had a comment line that exceeded 80
> lines ??? For the record, my perl executable didn't puke on this.


Have you actually tested that? To properly test it, you'll need to
have to the code as we received it, which is different from what
you started with.

Go back to
Date: Fri, 8 Jul 2005 15:36:31 -0400
Message-ID: <damkjv$k5k$(E-Mail Removed)>
select the text and copy-and-paste it into a new file. Then check
to see if your perl executable barfs on that.

I expect that you'll see the same thing we see: overly long comments
got mangled by the trip to USENET and back. If you can't get
the program to work after copy-and-paste, neither can we.
-Joe
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      07-10-2005
James Calivar <(E-Mail Removed)> wrote:
>>
>> Then, it is not clear at first sight, what is causing these problems.
>> Then, after some time, I realized the long, vanity comments. At that
>> point, I had no more motivation to try anything.
>>
>> I am glad Ala was able to help you (and I learned something from his
>> post). But the next time, I won't even see your post.
>>
>> Sinan
>>

>
> ??? You're *killfiling me* because I had a comment line that exceeded 80
> lines ???



No, the "disease" is that you did not make it easy for us to help you.

The "symptom" was posting code that we could not copy/paste and run.

The line-wrapping of the overly long comments (probably done by your
news posting client) made the code not even compile, let alone run.


> For the record, my perl executable didn't puke on this.



Then your "this" is not our "this".

We don't have your code. All we have is the code you showed us.

Have you tried running the actual code that you showed us? (rhetorical question)


> I guess ActiveState''s perl is at
> least smart enough to know that a comment should be treated as such.



You sure look silly now.


> Thanks for not helping,



Glad to join in and oblige.

*plonk*


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      07-11-2005
James Calivar wrote:
> Christ you people sure are intolerant. Enjoy your limited view of the
> Perl world, ****tard.


I will now

*PLONK*

jue


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic memory management, straightening my understanding of itsdetails Francesco S. Carta C++ 14 08-31-2010 08:56 PM
Project management / bug management Floris van Haaster ASP .Net 3 09-23-2005 08:36 PM
CatOS web management or CiscoView management ? Martin Bilgrav Cisco 1 12-20-2003 01:49 PM
Advice on implementing Exception Management Block SamIAm ASP .Net 1 08-04-2003 08:31 AM



Advertisments