Can I run two simultaneous non-nested loops in Perl?

advertisements

Part of my code goes like this:

while(1){
        my $winmm = new Win32::MediaPlayer;
        $winmm->load('1.mp3'); $winmm->play; $winmm->volume(100);
        Do Some Stuff;
        last if some condition is met;
    }

Problem is: I want the music to be always on when I'm in the Do Some Stuff stage in the while loop. But the length of the music is so short that it will come to a full stop before I go to the next stage, so I want the music to repeat itself, but the Win32::Mediaplayer module does not seem to have a repeat mode, so I'm thinking of doing an infinite loop for the music playing part. Like this:

while(1){
 my $winmm = new Win32::MediaPlayer;
 $winmm->load('1.mp3'); $winmm->play; $winmm->volume(100);
}
while(2){
Do some stuff;
last if some condition is met
}

But based on my current Perl knowledge if I'm in the while(1) part, I can never go to the while(2) part. Even if it comes to a nested loop, I have to do something to break out of the inside loop before going to the other part of the outside loop.

The answer to my question "Can we run two simultaneous non-nested loops in Perl?" may be a NO, but I assume there is some way of handling such situation. Correct me if I'm wrong.

Thanks as always for any comments/suggestions :)

UPDATE

I really appreciate the help from everyone. Thanks :) So the answer to my question is a YES, not a NO. I'm happy that I've learned how to use fork() and threads to solve a real problem :)


You can run the two different processes in separate threads.

Something along the lines of:

use strict;
use warnings;
use threads;
use threads::shared;
use Win32::MediaPlayer;

my $killAudio :shared = undef;
my $audio = threads->create(\&playAudio);
my $condition = threads->create(\&doSomething,$audio);
$condition->join();

sub playAudio {

    my $winmm = new Win32::MediaPlayer;
    $winmm->load('1.mp3') or die 'Could not load file: $!';
    $winmm->volume(100);
    $winmm->play until $killAudio;
}

sub doSomething {
    my $thread = shift;
    my $conditionMet = undef;

    while (1) {
        ($conditionMet,$killAudio) = doSomeStuff();    # set doSomeStuff() to
                                                       # return only when
                                                       # conditions are met

        $thread->join() if $killAudio;        # This line will terminate $audio
        last if $conditionMet;
    }
}

UPDATE

Based on Mike's comment below, the playAudio() subroutine can be rewritten as:

sub playAudio {
    my $winmm = new Win32::MediaPlayer;
    $winmm->load('1.mp3') or die 'Could not load file: $!';
    while (1) {
        $winmm->play;
        $winmm->volume(100);
        sleep($winmm->length/1000);
        last if $killAudio;
    }
}