Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Concurrent processes (waiting for children)

Reply
Thread Tools

Concurrent processes (waiting for children)

 
 
Jacob Heider
Guest
Posts: n/a
 
      05-07-2004
I've been following clpm for some months now, so hopefully I'll be able
to do this in a way that doesn't offend anyone.

I'm trying to write a console-based replacement for Grip, a
CD-ripper/-encoder under linux. In theory, I should be able to encode
the wav files while ripping subsequent once, since the actual CD-ripping
is IO-bound. The obvious way (to me, at least) is to fork a child to do
the encoding, and tell subsequent children not to start working until
prior children finish. (I think) I know why this doesn't work, i.e. the
first child isn't a child of the second child, etc., so waitpid won't
work. I know there got to be a better way, and probably at least a
half-dozen ways which could work. Please help.

The code (excerpt) which doesn't work is (some lines split to get under
72-characters):


#!/usr/bin/perl

use warnings;
use strict;

my $lastpid;

for (my $i = 1; $i <= 5; $i++) {

system("cdda2wav -D /dev/cdrom -I cooked_ioctl -P 0 -t $i"
"-O wav -H -g $i.wav") == 0
or die "cdda2wav failed: $?\n";

my $childpid = fork;
die "fork failed: $?\n" unless defined($childpid);

if ($childpid == 0) {

if ($lastpid) {
waitpid($lastpid, 0);
}

system("lame -V 3 $i.wav $i.mp3") == 0
or die "lame failed: $?\n";
system("oggenc -q 3 -o $i.ogg $i.wav") == 0
or die "oggenc failed: $?\n";
system("flac -6 -o $i.flac $i.wav") == 0
or die "flac failed: $?\n";

system("rm $i.wav");

exit;

}

$lastpid = $childpid;
}

__END__

The system calls could be anything, of course, but these are the
applications I'm calling. I have looked a Parallel::ForkManager, but
since this project is to get me into perl from a primarily C background,
I'm trying to be thorough in exploring my options.

Someday I hope to wrap this baby in a quality curses GUI (since I'm sick
to death of non-text apps), but if I can get the guts to run, I'll be
most of the way towards having something useful.

Thanks for the help,

Jacob
 
Reply With Quote
 
 
 
 
Sam Holden
Guest
Posts: n/a
 
      05-07-2004
On Fri, 07 May 2004 07:08:51 GMT, Jacob Heider <(E-Mail Removed)> wrote:
> I've been following clpm for some months now, so hopefully I'll be able
> to do this in a way that doesn't offend anyone.
>
> I'm trying to write a console-based replacement for Grip, a
> CD-ripper/-encoder under linux. In theory, I should be able to encode
> the wav files while ripping subsequent once, since the actual CD-ripping
> is IO-bound. The obvious way (to me, at least) is to fork a child to do
> the encoding, and tell subsequent children not to start working until
> prior children finish. (I think) I know why this doesn't work, i.e. the
> first child isn't a child of the second child, etc., so waitpid won't
> work. I know there got to be a better way, and probably at least a
> half-dozen ways which could work. Please help.


I'd approach it by forking a process that just keeps encoding
files until told to stop it would look something like:

#note: completely untested... not even executed once...

sub encode_files {
while (my $file = <READER>) {
chomp $file;
system("lame -V 3 $file.wav $file.mp3") == 0
or die "lame failed: $?\n";
system("oggenc -q 3 -o $file.ogg $file.wav") == 0
or die "oggenc failed: $?\n";
system("flac -6 -o $file.flac $file.wav") == 0
or die "flac failed: $?\n";
}
}

#create a pipe
pipe(READER,WRITER) or die "Unable to pipe: $!";
$| = 1, select $_ for select WRITER;

#fork a child and set it to work
my $childpid = fork();
die "fork failed: $?\n" unless defined($childpid);
if ($childpid == 0) {
encode_files();
exit(0);
}

for my $i (1 ... 5) {
system("cdda2wav -D /dev/cdrom -I cooked_ioctl -P 0 -t $i" .
"-O wav -H -g $i.wav") == 0
or die "cdda2wav failed: $?\n";
print WRITER "$i\n";
}
close WRITER;
wait();


Though I'd use the list form of system to stop the shell from
seeing the commands, and I'd pass an IO::Handle or a GLOB reference
to encode_files.

There might be blocking issues with the pipe, in which case you could
use a temporary file, and treat a blank line as a terminate signal
instead of eof.

I guess you could just open( WRITER, "|xargs [appropriate arguments")
where two of the appropriate arguments will be -l and -i instead of
the fork and child loop.

[snip code, most of which has been copied into the code above...]

--
Sam Holden
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Controlling processes and what to "feed" other processes Marc Heiler Ruby 1 05-24-2009 05:37 PM
multiple concurrent processes Wernt Me Java 7 01-04-2006 10:58 PM
problems locating the concurrent EDU.oswego.cs.dl.util.concurrent package Pep Java 6 08-16-2005 07:26 AM
Concurrent ICS + wireless print server usage =?Utf-8?B?QW5keVM=?= Wireless Networking 3 04-21-2005 06:23 PM
How do I: Main thread spawn child threads, which child processes...control those child processes? Jeff Rodriguez C Programming 23 12-09-2003 11:06 PM



Advertisments