[18995] in Perl-Users-Digest
Perl-Users Digest, Issue: 1190 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Jun 25 14:10:47 2001
Date: Mon, 25 Jun 2001 11:10:10 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <993492610-v10-i1190@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Mon, 25 Jun 2001 Volume: 10 Number: 1190
Today's topics:
Re: puzzled over fork() doing something different to bo <m.grimshaw@salford.ac.uk>
Re: puzzled over fork() doing something different to bo <pne-news-20010625@newton.digitalspace.net>
Re: puzzled over fork() doing something different to bo (Mark Jason Dominus)
Re: puzzled over fork() doing something different to bo (Anno Siegel)
Re: puzzled over fork() doing something different to bo <buggs-clpm@splashground.de>
Re: puzzled over fork() doing something different to bo <m.grimshaw@salford.ac.uk>
Re: puzzled over fork() doing something different to bo (Mark Jason Dominus)
Re:THE fastest way to count lines in a file <torelg@hotmail.com>
Re: regular expression problem <ren@tivoli.com>
Re: using dbmopen() (Anno Siegel)
Re: using dbmopen() (Mark Jason Dominus)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Mon, 25 Jun 2001 16:25:58 +0100
From: Mark Grimshaw <m.grimshaw@salford.ac.uk>
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <3B375806.BF8FB09C@salford.ac.uk>
Buggs wrote:
>
> Mark Grimshaw wrote:
>
> > Here's the script:
> > #!/usr/local/bin/perl -wl
>
> read about the -l switch
>
> > According to the book (and it seems logical too), my parent process will
> > execute first, then the child, then the parent, then the child etc. etc.
> > etc. The book claims I will get something like:
>
> It could. The processes will be scheduled by the kernel,
> but you can't say which executes when.
>
>
>
> > However, the result of running this script is:
> >
> > hexie 593% ./fork.pl
> > I'm the child. Be nice to me!
>
> The child got scheduled before the parent, not unusual.
> Read your OS docu to get a finer grained understanding
> of the kernel scheduling.
>
> >
> > I'm the parent. Please yell at my child.
> >
> > hi there
>
> Actually perl reads this as
>
> hi there\n
>
> and you write it in your pipe as
>
> hi there\n\n
>
> because the -l switch appends \n on print()
>
> > Parent said: hi there
> >
> >
> > Parent said:
> >
>
> So you get two lines when you read the pipe
> both a printed out
> 1. hi there\n
> 2. \n
>
> Have fun,
> Buggs
ok - removing the -l switch has solved the 'half-execution'. How do I
force the parent to execute first?
------------------------------
Date: Mon, 25 Jun 2001 17:42:25 +0200
From: Philip Newton <pne-news-20010625@newton.digitalspace.net>
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <mqmejt4h0l01gl95eamr9s75nl457de7i6@4ax.com>
On Mon, 25 Jun 2001 16:25:58 +0100, Mark Grimshaw
<m.grimshaw@salford.ac.uk> wrote:
> How do I force the parent to execute first?
Reprogram the task scheduler in your operating system? :)
Seriously, though -- if you fork(), the resulting processes conceptually
run simultaneously and concurrently. One doesn't generally run before or
after the other.
What you could do, for example, is put a sleep() at the beginning of the
child process (which doesn't guarantee anything, as the parent process
might take longer to set stuff up than you slept in the child), or
immediately try to read from the pipe (which will block until the parent
writes to it), or something like that.
Cheers,
Philip
--
Philip Newton <nospam.newton@gmx.li>
Yes, that really is my address; no need to remove anything to reply.
If you're not part of the solution, you're part of the precipitate.
------------------------------
Date: Mon, 25 Jun 2001 15:47:42 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <3b375d1e.6c5f$2a7@news.op.net>
In article <3B375806.BF8FB09C@salford.ac.uk>,
Mark Grimshaw <m.grimshaw@salford.ac.uk> wrote:
>ok - removing the -l switch has solved the 'half-execution'. How do I
>force the parent to execute first?
You can't. The OS will schedule the two processes whenever it wants.
You need to write the program so that the behavior does not depend on
the order in which the processes are executed.
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print
------------------------------
Date: 25 Jun 2001 15:48:23 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <9h7mg7$3c1$2@mamenchi.zrz.TU-Berlin.DE>
According to Mark Grimshaw <m.grimshaw@salford.ac.uk>:
> Buggs wrote:
> >
> > Mark Grimshaw wrote:
> >
> > > According to the book (and it seems logical too), my parent process will
> > > execute first, then the child, then the parent, then the child etc. etc.
> > > etc. The book claims I will get something like:
> >
> > It could. The processes will be scheduled by the kernel,
> > but you can't say which executes when.
[snip-a-rone]
> ok - removing the -l switch has solved the 'half-execution'. How do I
> force the parent to execute first?
You don't. You can't. It's up to the system which process runs
first.
All you can do is arrange for the processes to behave *as if* the
parent started first. The child could silently wait for something
the parent sends over the pipe, for instance.
Anno
------------------------------
Date: Mon, 25 Jun 2001 18:06:33 +0200
From: Buggs <buggs-clpm@splashground.de>
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <9h7nc5$12j$05$1@news.t-online.com>
Mark Grimshaw wrote:
--snip--
>> The child got scheduled before the parent, not unusual.
>> Read your OS docu to get a finer grained understanding
>> of the kernel scheduling.
>>
--snip--
> ok - removing the -l switch has solved the 'half-execution'. How do I
> force the parent to execute first?
Actually one reason to fork is
to overcome linear execution.
Is reading docu an option? :)
This is not an easy topic.
A bit reading about kernel scheduling, processes and
maybe multithreading will really help you.
Just skim a bit over these topics,
it will get you the context.
Maybe you just get happy with a short sleep() in your child.
Buggs
------------------------------
Date: Mon, 25 Jun 2001 18:28:24 +0100
From: Mark Grimshaw <m.grimshaw@salford.ac.uk>
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <3B3774B8.4646B824@salford.ac.uk>
<snip>
>
> Is reading docu an option? :)
>
> This is not an easy topic.
>
<snip>
Makes sense now.
I think this is my first post here where I've been told to go read the
documentation! I thought I'd been doing pretty well until then.... :)
Of course I read documentation and all my perl books on fork()! If I
was a UNIXhead or perl guru, I wouldn't be asking questions here would I
now? man fork is pretty impenetrable stuff (to me) as, to a lesser
extent, is perldoc perlipc. perldoc -q fork talks about daemon
processes. perldoc -f fork is very short and mainly seems to state the
need to use wait() which doesn't seem to be the whole truth when I
combine it with pipes. The following works perfectly well, does what I
expect it to do and creates no zombies - and not a wait() in sight (it
sits there looping away until I CTRL-C):
#!/usr/local/bin/perl -w
use strict;
use FileHandle;
pipe(READ_P, WRITE_C);
pipe(READ_C, WRITE_P);
WRITE_P->autoflush();
WRITE_C->autoflush();
my $pid = fork;
my $index = 0;
if($pid == 0)
{
close READ_C;
close WRITE_C;
print WRITE_P "$index\n";
while(<READ_P>)
{
print "\t\t\tParent said: $_\n";
sleep 2;
++$index;
print WRITE_P "$index\n";
}
}
elsif(defined $pid)
{
close READ_P;
close WRITE_P;
while(<>)
{
last;
}
while(<READ_C>)
{
print "child said index = $_\n";
sleep 2;
print WRITE_C "give me another!\n";
}
}
else
{
print "couldn't fork\n\n";
}
As you say, 'this is not an easy topic' and a combination of books, man,
perldoc, my own experimentation and, as a final resort, answers from
here usually leads me to the solution by collating some understanding
from each. What throws me off my stride is when the example from a book
does not do exactly what that book says it will do (I'll grant that the
-l switch was a leftover from previous scripts that I didn't take out -
the order of execution was still different without it), nor does the
book state that the order of execution of processes may not be exactly
that given. Perhaps I'm _too_ trusting of the documentation ;)
------------------------------
Date: Mon, 25 Jun 2001 17:39:07 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: puzzled over fork() doing something different to book example
Message-Id: <3b37773b.6ef3$132@news.op.net>
In article <3B3774B8.4646B824@salford.ac.uk>,
Mark Grimshaw <m.grimshaw@salford.ac.uk> wrote:
>The following creates no zombies - and not a wait() in sight
When the child exits, it becomes a zombie. The reason you don't see
this is that the parent exits at almost the same time, and the zombie
is automatically adopted by the 'init' process. Init runs a program
that looks something like this:
while (1) {
wait;
}
which cleans up the zombie immediately.
I suggest you get the Richard W. Stevens book about Advanced
Programming in the Unix Environment. Sooner or later you are going to
run into a problem you can't solve without an understanding of what is
really going on.
>nor does the book state that the order of execution of processes may
>not be exactly that given.
Get a better book.
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print
------------------------------
Date: Mon, 25 Jun 2001 18:08:15 +0200
From: "toreLG" <torelg@hotmail.com>
Subject: Re:THE fastest way to count lines in a file
Message-Id: <%jJZ6.5304$sC3.90665@news1.oke.nextra.no>
The fastest way to count lines, is:
$count += tr/\n/\n/ while sysread(FILE, $_, 2 ** 16);
proveded your line terminators are newlines (\n).
- toreLG.
------------------------------
Date: 25 Jun 2001 10:04:34 -0500
From: Ren Maddox <ren@tivoli.com>
Subject: Re: regular expression problem
Message-Id: <m3ae2wa9dp.fsf@dhcp9-173.support.tivoli.com>
On Sat, 23 Jun 2001, wyzelli@yahoo.com wrote:
> "Xtreme" <lxl22@visto.com> wrote in message
> news:91ff860e.0106221022.505ce10d@posting.google.com...
>>
>> Thanks, Peter. I had forgotten to mention that a,b and c can each
>> be distinct or the same -- I don't know ahead of time, and that I
>> don't want to replace a or c (i.e. not the first or last in the
>> string). I figured it out in the mean time by going through (of
>> all things) the faq: s/\G_b_/_x_/g; I still don't really grasp the
>> \G, but it works!
>
> It actually isn't necessary. s/_b_/_x_/g will also work fine.
Actually, that doesn't work. Of course, it doesn't work with the \G
either, but the behavior is different.
#!/usr/bin/perl
$_ = "b_b_b_b";
{ local $_ = $_; s/\G_b_/_x_/g; print "$_\n" }
{ local $_ = $_; s/_b_/_x_/g; print "$_\n" }
{ local $_ = $_; s/(?<=_)b(?=_)/x/g; print "$_\n" }
__END__
b_b_b_b
b_x_b_b
b_x_x_b
So with the \G, nothing happens. Without it, only every other
consecutive internal occurrence is replace.
--
Ren Maddox
ren@tivoli.com
------------------------------
Date: 25 Jun 2001 15:36:53 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: using dbmopen()
Message-Id: <9h7lql$3c1$1@mamenchi.zrz.TU-Berlin.DE>
According to Aman Patel <patelnavin@icenet.net>:
> just a simple question. What kind of file does dbmopen() bind a hash to (BY
> DEFAULT). I saw the perlfunc man page, and found that:
>
> This binds a dbm(3), ndbm(3), sdbm(3), gdbm(3), or Berkeley DB file to a
> hash.
>
> But un-fortunately, they havent mentioned on the type of DB, file that it
> binids the hash to by default. The manual also states how to tell the
> dbmopen(), to use a kind of DB file, like this:
>
> use DB_File; #tell dbmopen to use DB_File
> dbmopen(....
> ....
> dbmclose(...);
>
> But if I remove the first line 'use DB_File', what will the program use.
Well, what happened when you tried it?
The manual doesn't mention a default for dbmopen because there is
none. It uses whatever *_File module you loaded. BTW, dbmopen really
exists only for backwards-compatibility. New code should use tie
instead.
Anno
------------------------------
Date: Mon, 25 Jun 2001 17:14:34 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: using dbmopen()
Message-Id: <3b37716e.6e4e$120@news.op.net>
In article <9h7h8k$c6aej$1@ID-93885.news.dfncis.de>,
Aman Patel <patelnavin@icenet.net> wrote:
>just a simple question. What kind of file does dbmopen() bind a hash to (BY
>DEFAULT). I saw the perlfunc man page, and found that:
>
>This binds a dbm(3), ndbm(3), sdbm(3), gdbm(3), or Berkeley DB file to a
>hash.
>
>But un-fortunately, they havent mentioned on the type of DB, file that it
>binids the hash to by default.
It depends on which version of Perl you have. dbmopen loads
AnyDBM_File.pm, which then tries to load a DBM module until it finds
one that works. The first one that works is the one it uses.
If you look into the AnyDBM_File.pm module with (perldoc -m
AnyDBM_File), you will see the order in which it will try the DBM
modules.
In Perl 5.6.1, the order is:
NDBM_File DB_File GDBM_File SDBM_File ODBM_File
If you want a different order, you may put this in your program:
BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) }
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 1190
***************************************