Problems understanding and implementing process management

Discussion in 'Perl Misc' started by James Calivar, Jul 8, 2005.

  1. 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
     
    James Calivar, Jul 8, 2005
    #1
    1. Advertising

  2. James Calivar

    Ala Qumsieh Guest

    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
     
    Ala Qumsieh, Jul 8, 2005
    #2
    1. Advertising

  3. "Ala Qumsieh" <> wrote in message
    news:hWyze.3188$6%...
    > 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++;
    }
     
    James Calivar, Jul 8, 2005
    #3
  4. "James Calivar" <> wrote in
    news:damkjv$k5k$:

    > 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 <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jul 8, 2005
    #4
  5. James Calivar

    Ala Qumsieh Guest

    James Calivar wrote:
    > "Ala Qumsieh" <> 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
     
    Ala Qumsieh, Jul 9, 2005
    #5
  6. James Calivar <> wrote in
    news:hZIze.19925$:

    > A. Sinan Unur wrote:
    >> "James Calivar" <> wrote in
    >> news:damkjv$k5k$:
    >>
    >>
    >>>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 <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jul 9, 2005
    #6
  7. James Calivar <> wrote:


    > I'm a pretty new Perl programmer,



    I'm a ugly old Perl programmer.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jul 9, 2005
    #7
  8. James Calivar

    Joe Smith Guest

    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$>
    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
     
    Joe Smith, Jul 10, 2005
    #8
  9. James Calivar <> 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
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jul 10, 2005
    #9
  10. James Calivar wrote:
    > Christ you people sure are intolerant. Enjoy your limited view of the
    > Perl world, fucktard.


    I will now

    *PLONK*

    jue
     
    Jürgen Exner, Jul 11, 2005
    #10
  11. James Calivar <> writes:

    > Christ you people sure are intolerant. Enjoy your limited view of the
    > Perl world, fucktard.


    I didn't killfile you before, but I certainly will now.

    *plonk*

    sherm--

    --
    Cocoa programming in Perl: http://camelbones.sourceforge.net
    Hire me! My resume: http://www.dot-app.org
     
    Sherm Pendley, Jul 11, 2005
    #11
  12. James Calivar <> wrote:
    > Tad McClellan wrote:
    >>
    >> Glad to join in and oblige.
    >>
    >> *plonk*
    >>
    >>

    >
    > Christ you people sure are intolerant.



    The code would not compile, you insisted it would compile, we are
    intolerant of the possibility of impossible things happening.

    Such intolerance is common even outside of this newsgroup.


    > Enjoy your limited view of the
    > Perl world,



    Most people would have apologized for the broken code, fixed it,
    and gotten some help with it.

    It appears you are not such a person.

    (and, since the code would not compile, it was NOT a member of the
    set comprising the "Perl world".
    )


    > fucktard.



    I love you too.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jul 11, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. SamIAm
    Replies:
    1
    Views:
    354
    vineet.batta
    Aug 4, 2003
  2. Floris van Haaster

    Project management / bug management

    Floris van Haaster, Sep 23, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    1,267
    Jon Paal
    Sep 23, 2005
  3. pouet
    Replies:
    2
    Views:
    808
    Will Hartung
    Jul 30, 2004
  4. Francesco S. Carta
    Replies:
    14
    Views:
    557
    Francesco S. Carta
    Aug 31, 2010
  5. Replies:
    0
    Views:
    95
Loading...

Share This Page