Domanda

Una parte del mio codice va in questo modo:

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

Il problema è: voglio che la musica sia sempre quando mi trovo in Do un certo punto Stuff nel ciclo while. Ma la lunghezza della musica è così breve che si arriverà a un punto fermo prima di andare alla fase successiva, quindi voglio che la musica si ripete, ma il Win32 :: modulo di Mediaplayer non sembra avere una modalità di ripetizione, così sto pensando di fare un ciclo infinito per la parte la riproduzione di musica. In questo modo:

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
}

Ma in base alla mia conoscenza di Perl corrente se io sono nel mentre (1) parte, non potrò mai andare al while (2) parte. Anche se si tratta di un ciclo nidificato, devo fare qualcosa per uscire dal ciclo interno prima di andare a l'altra parte del circuito esterno.

La risposta alla mia domanda "Possiamo eseguire due cicli non nidificati simultanee in Perl?" può essere un NO, ma assumere c'è qualche modo di gestire tale situazione. Correggimi se sbaglio.

Grazie come sempre per eventuali commenti / suggerimenti:)

Aggiorna

Ho davvero apprezzato l'aiuto da parte di tutti. Grazie :) Quindi la risposta alla mia domanda è un sì, non è un NO. Sono contento che ho imparato come usare fork () e le discussioni per risolvere un problema reale:)

È stato utile?

Soluzione

È possibile eseguire i due processi differenti in thread separati.

Qualcosa sulla falsariga di:

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

Aggiorna

In base a commento di Mike di seguito, la subroutine playAudio() può essere riscritto come:

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

Altri suggerimenti

Puoi provare a forcella, in questo modo:

Quindi si creerà 2 fili, uno dei quali riprodurre la vostra musica e la seconda farà tutto il vostro altre cose.

Si dovrebbe anche pensare a terminare tuo thread musica di qualche condizione

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

Se la fase doSomething() si inserisce naturalmente all'interno di una struttura loop, si può semplicemente verificare lo stato della canzone periodicamente e seek di nuovo all'inizio se la canzone è finita -. Certamente un hack, ma facile

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top