weismat has asked for the wisdom of the Perl Monks concerning the following question:

I have written a multi-threaded Perl program which runs under Windows. It is multithreaded for good performance reasons, so all socket operations run in different threads. I would like to control the behaviour of this program externally. Unfortunately Windows does not support signals, thus I am considering to add a GUI to this program. Has anyone done something similar and can share his experience? If I use e.g. TK, it is a problem that I will change shared variables which are read by the other threads? Would you recommend any alternatives?
  • Comment on External controlling of a multi-threaded Windows perl program

Replies are listed 'Best First'.
Re: External controlling of a multi-threaded Windows perl program
by moritz (Cardinal) on Nov 02, 2007 at 12:47 UTC
    My suggestion is to let your program listen at a socket or TCP port, so you can completely decouple the control process from the front end, and then perhaps provide a command line and/or a GUI front end.

    That way it might a little bit harder, but you can debug front end and backend separately, and you greatly simplify unit testing.

      I have decided to go this route. When assuming that there is only one client for the program, then things are relatively easy. The unit testing part is important. I could not really use Windows signals as I need at least two signals. I remember catching Ctrl+C under Windows a long time ago, but I think there was an issue with threads then.
Re: External controlling of a multi-threaded Windows perl program
by jplindstrom (Monsignor) on Nov 02, 2007 at 13:57 UTC
    If you're doing a GUI it's a good idead to keep it in a thread of its own.

    Create a thread first and don't load any GUI modules at all before that, then build the GUI and run main event loop in that one.

    Use things like Thread::Queue or Thread::Queue::Any to communicate between the threads.

    /J

      I am using Thread::Queue already. Most of my multithreaded modules use this module. Only if I need real two-way communication, than I use the cond_wait and cond_signal. I have some experience with POSIX threads and the queue implementation in Perl is really elegant.
Re: External controlling of a multi-threaded Windows perl program
by cdarke (Prior) on Nov 02, 2007 at 15:23 UTC
    Unfortunately Windows does not support signals

    Not properly, anyway. But there plenty of alternatives - it really depends on what you want to do. "Signalling" another process can be done using Windows events. Just have a thread waiting on a specified event, and write a small command-line program to raise it.

    Alternatively, CTRL-C (SIGINT) type events (and a couple of others) can be raised using the Win32 API GenerateConsoleCtrlEvent. Use SetConsoleCtrlHandler to catch it (a bit like a signal handler). Since all processes sharing the same console (even when it is hidden with SW_HIDE) get the CTRL-C, it is possible to emulate the idea of a UNIX terminal group.
Re: External controlling of a multi-threaded Windows perl program
by zentara (Cardinal) on Nov 02, 2007 at 16:34 UTC
    If I use e.g. TK, it is a problem that I will change shared variables which are read by the other threads? Would you recommend any alternatives?

    You can isolate shared variables so that each thread has it's own, by setting up a hash (or array) of shared vars, one for each thread. Here is an examle Tk-with-worker-threads. Remember, with Tk, you need to start all threads before any Tk code is called. That means you will need to predefine the number of threads available, and possibly reuse them. Gtk2 (GLib) has better thread safety, and if you are very lucky you may be able to dynamically create threads. I have been testing this idea from time to time, and it is NOT foolproof. Sometimes it works, sometimes a segfault, sometimes a memory gain. So the same advice applies to Gtk2 as to Tk: create your threads first before any GUI code is called for rock-solid performance. But you may want to switch to Gtk2 (GLib) for better thread safety, if you need to dynamically spawn threads.

    The only other alternative is to use POE. It has no gui code, and may allow dynamic threads without problems.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: External controlling of a multi-threaded Windows perl program
by BrowserUk (Patriarch) on Nov 02, 2007 at 17:06 UTC
    I would like to control the behaviour of this program externally.

    What do you mean by that?

    For example, if you mean starting and stopping it when it is running in the background, take a look at Win32::Daemon::Simple to make your program run as a Windows Service. It can then be 'controlled' in the usual ways using the MMC.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.