in reply to Looping in the background of your main program

If I'm understanding you correctly, you want to execute some code outside of the loop while the songs are playing.  As the playing itself already appears to happen in the background, the most simple approach would be to call some other routine in your program every time you get around to calling sleep at the end of the loop, and when that routine returns, just sleep for the remaining time only (i.e. song length minus time the routine took). That would mean your other code executes synchronously with the loop iterations, so a single call of the routine may not take more time than the length of the current song allows. — In other words, make that while loop the main loop of your program and arrange the other code around it.

If you need asynchronous execution, you could use threads or fork a separate process. Which technique to use depends on a number of factors, for example how you want to share data. The latter is somewhat simpler with threads, because different processes (as created with fork) would require interprocess communication (IPC), such as pipes, sockets and signals, to explicitly exchange information.

Replies are listed 'Best First'.
Re^2: Looping in the background of your main program
by Baphi (Acolyte) on Dec 30, 2009 at 17:40 UTC
    thanks for your reply almut, I beleive forking would be my number one choice here, however I have been looking online and reading but still do not understand how to fork a process and use my variables from my main process there aswell, if anyone can explain this to me it would be great. thank you.
      but still do not understand how to fork a process and use my variables from my main process there aswell

      The point is, you can't (directly). At the time of forking, all program data (including variables with their current values) are being duplicated, but from that point onwards, updates to the two copies of the variables do happen independently.  It's for that reason that you'd then need IPC.

      With threads and threads::shared, OTOH, you can tell Perl which variables you want to share across the different threads.  But threads may be problematic in other ways, for example in that code (which you've loaded before creating a new thread) needs to be thread-safe — which in particular external libraries (as often needed with XS modules) sometimes aren't.

      Perl threads are a big and rather cludgy hammer, and should only be used when you need to share lots of data between many processes. They're great to have when you truly need them, but in your case, you don't truly need them. :)

      Since you know exactly how long you want to wait, you can simply use the alarm function. You've got high precision for your timing, so you should probably use the Time::HiRes module, which is almost certainly a core module for you. To get all of this to work, a skeleton of your code might look like this:

      use Time::HiRes qw(alarm); # Pre-declare any variables you'll need in play_func and in # the main code my %all_files; sub play_func { ## Most of your originally posted code goes here, but ## replace the call to sleep with this: alarm ($song_length); } # You'll need to associate the alarm signal handler with # play_func like so: $SIG{ALRM} = \&play_func; # Initialize your data here, such as your playlist # Kick-off the play loop by calling play_func once: play_func(); # Put your own looping/interface code here: while(1) { # This will loop until you call 'last;' or exit. # When the alarm signal goes off, Perl will jump to # your alarm-handling code and execute that, then # return to whatever it was doing in here. # This will lead to a slight interrupt in this loop, # but it probably won't be noticeable. }

      Hope that's a useful alternative approach!