0

I was playing with this code, from the way the beep is sounding, once the program starts it doesn't stop. I suspect the problem is with $thread->kill('KILL')->detach;.

Any ideas? Or have I done something wrong ?

#!c:/perl/bin/perl

use threads;
use Audio::Beep;

my $thread;
my $playing=0;

while (1) {
  my $val = int( rand(10) );
  print "$val\n";

  # if event "start" occurs and is not playing create thread
  #if ( ($val==0 || $val==1 || $val==2 || $val==3 || $val==4 ) && (!$playing) ) {
  if ( ($val==0 || $val==1 || $val==2 ) && (!$playing)  ) {
    $playing = 1;
    $thread = threads->create( 
      sub {
        local $SIG{'KILL'} = sub { threads->exit() };
        print "start beep\n";
        beep( 520, 10000 );
      } 
    );
  }
  # if event "end" occurs and playing wait 1 seconf and kill thread
  elsif ( ($val==5 ) && $playing ) {
    print "stop beep \n";
    #sleep(1);  
    $playing = 0;
    $thread->kill('KILL')->detach;
  }

  #sleep(1);

  $count = 0;
  for($i=0; $i<99999 ; $i++) {
     $count++;
  }
}
Syd
  • 185
  • 1
  • 14
  • install audio beep and try the script. it doesnt stop ... you can make the scrip run slower by duplicating the for loop 99999 below. previously it was running really slowly and it still did not stop. – Zubinn Tan May 24 '13 at 10:57
  • Your infinite look has a 30% chance of spawning a 10 second beep, and only a 10% chance of attempting to kill that beeper. How do you know the kill isn't working, and then a new beeper is simply spawned? If you put a print inside your SIG{KILL} handler, does it get called? – pilcrow May 25 '13 at 03:48

1 Answers1

0

I think your program is mostly working as you intend. One of the problems with what I see now is that every beep sounds alike. I re-wrote it a little to give the beep some texture, and to slow things down so that you can appreciate what's happening.

Also, as you've written it, there's a possibility that the thread will end on its own, before you can kill it. I've made the thread persistent, and added additional diagnostic information which will confirm when the thread is running and when it is not.

use strict;
use warnings;
use threads;
use Audio::Beep;

my $thread;
my $playing=0;

while (1) {
  my $val = int( rand(30) );
  print "$val\n";
  my $running = threads->list(threads::running);
  print "Threads running: $running\n";

  # if event "start" occurs and is not playing create thread
  if ( ( $val==1 ) && (!$playing)  ) {
    $playing = 1;
    print ">>>>>>>>\n";
    sleep(1);
    $thread = threads->create( 
      sub {
        local $SIG{'KILL'} = sub { threads->exit() };
        print "start beep\n";
        while (1) {
          beep( 520, 100 );
          sleep(1);
          beep( 3800, 100 );
          sleep(1);
          beep( 2000, 100);
          sleep(1);
        }
      } 
    );
  }
  # if event "end" occurs and playing wait 5 seconds and kill thread
  elsif ( ($val==2 ) && $playing ) {
    print "STOPSTOPSSTOPSTOPSTOP\n";
    sleep(5);  
    $thread->kill('KILL')->detach;
    $playing = 0;
  }

  for(my $i=0; $i<999999 ; $i++) {}
}
mcduffee
  • 1,237
  • 1
  • 10
  • 14