Мы можем выполнить два одновременных невложенных цикла в Perl?

Часть моего кода идет как это:

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;
    }

Проблема: Я хочу, чтобы музыка была всегда включена, когда я нахожусь в Некоторого этапа Материала в цикле с условием продолжения. Но длина музыки так коротка, что она прибудет в точку, прежде чем я перейду к следующему этапу, таким образом, я хочу, чтобы музыка повторилась, но Win32:: модуль Mediaplayer, кажется, не имеет повторный режим, таким образом, я думаю о выполнении бесконечного цикла для музыкальной роли играющего. Как это:

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
}

Но на основе моего текущего знания Perl, если я нахожусь в, в то время как (1) часть, я никогда не могу переходить в в то время как (2) часть. Даже если это приходит к вложенному циклу, я должен сделать что-то для убегания из внутреннего цикла прежде, чем идти в другую часть внешнего цикла.

Ответ на мой вопрос "Мы можем выполнить два одновременных невложенных цикла в Perl?" может быть a нет, но я предполагаю, что существует некоторый способ обработать такую ситуацию. Исправьте меня, если я неправ.

Спасибо как всегда за любые комментарии/предложения :)

ОБНОВЛЕНИЕ

Я действительно ценю справку от всех. Спасибо :) Таким образом, ответ на мой вопрос является a ДА, не НЕТ. Я рад, что изучил, как использовать ветвление () и потоки для решения настоящей проблемы :)

7
задан Mike 12 March 2010 в 03:43
поделиться

3 ответа

Вы можете запустить два разных процесса в отдельных потоках.

Что-то вроде:

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

Основываясь на комментарии Майка ниже, подпрограмму playAudio() можно переписать так:

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;
    }
}
10
ответ дан 6 December 2019 в 10:49
поделиться

Вы можете попробовать выполнить форк, например:

Итак, вы создаст 2 потока, один из которых будет воспроизводить вашу музыку, а второй - все остальное.

Вам также следует подумать о завершении вашего музыкального потока некоторым условием

    my @child_pids = ();
    my $pid = fork();
    if ($pid)
    {
        # parent
        push(@child_pids, $pid);
        Do some stuff;
        last if some condition is met
    }
    elsif ($pid == 0)
    {
        # child
        while(1){
         my $winmm = new Win32::MediaPlayer;   
         $winmm->load('1.mp3'); $winmm->play; $winmm->volume(100);
        }
        exit(0);
    }
    else
    {
        die "couldn’t fork: $!\n";
    }
6
ответ дан 6 December 2019 в 10:49
поделиться

Если ваша сцена doSomething() естественно вписывается в циклическую структуру, вы можете просто периодически проверять состояние песни и искать начало, если песня закончилась - конечно, это хак, но простой.

use strict;
use warnings;

use Win32::MediaPlayer;
my $winmm = Win32::MediaPlayer->new;

$winmm->load($ARGV[0]) or die $!;
$winmm->play;
my $end_of_song = $winmm->length;

# doSomething
for (1 .. 1000){
    # Perform difficult computations...
    sleep 2;

    # Has song ended?
    $winmm->seek(0) if $winmm->pos >= $end_of_song;
}
2
ответ дан 6 December 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: