You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by harm <ha...@tty.nl> on 2002/10/29 21:59:13 UTC

Same $dbh under different pids?

Moi,

a quick question: is it possible to have the 'same' dbh across the apache
children even if you do your best not to?

This minimalistic handler:
use strict;
package Foo;
use Apache::DBI;
use DBI;
use Apache::Constants qw':common';

my $dbh;
$Apache::DBI::DEBUG = 1;

sub handler {
   my $r = shift;
   $r->send_http_header;
   $r->print("ok");
   $dbh ||= DBI->connect("dbi:mysql: ... etc);
   $r->print("dbh: ", $dbh, " ($$)<br>\n");
   return OK;
}
1;

Gives me:
okdbh: Apache::DBI::db=HASH(0x8269a88) (84889)
<reload>
okdbh: Apache::DBI::db=HASH(0x8269a88) (84885)
<reload>
okdbh: Apache::DBI::db=HASH(0x8269a88) (84886)
<reload>
okdbh: Apache::DBI::db=HASH(0x8269a88) (84887)
<reload>
okdbh: Apache::DBI::db=HASH(0x8269a88) (84888)


Is it normal all the $dbh-s have the same 'Apache::DBI::db=HASH(0x8269a88)'
?

Thanks,

Harmen


-- 
                               The Moon is Waning Crescent (43% of Full)

Re: Same $dbh under different pids?

Posted by Perrin Harkins <pe...@elem.com>.
Mrs. Brisby wrote:

>$ perl -e '$foo = {}; fork; print "$$:$foo\n";'
>18161:HASH(0x80fd254)
>18162:HASH(0x80fd254)
>$ perl -e 'fork; $foo = {}; print "$$:$foo\n";'
>18163:HASH(0x80fd254)
>18164:HASH(0x80fd254)
>

I expected the first.  I didn't expect the second.  Thanks for the 
explanation.

- Perrin


Re: Same $dbh under different pids?

Posted by "Mrs. Brisby" <mr...@nimh.org>.
On Wed, 2002-10-30 at 14:52, Perrin Harkins wrote:
> harm wrote:
> 
> >On Wed, Oct 30, 2002 at 06:05:51PM +0800, Philippe M. Chiasson wrote:
> >  
> >
> >>For the same reason that running this:
> >>$> perl -e'fork; { $foo = {}; print "$$:$foo\n"}'
> >>1984:HASH(0x804c00c)
> >>1987:HASH(0x804c00c)
> >>
> >>produces this for me, every single time I run this program
> >>
> >>You are assuming that if (0x804c00c) is equal in different processes,
> >>they must be pointers(or references, or handles) to the same thing. And
> >>it is not the case ;-)
> >>
> 
> Wait, ins't it the case?  That number is supposed to be the location in 
> memory.  It seems like these are all pointing to the same hash.  I can't 
> explain how that would happen though, based on the code shown here.

You're confusing virtual memory with physical memory. Given an SMP
system where pid 1984 and 1987 can both actually run at the same time
(thus ensuring neither is "swapped out") address 0x804c00c actually
occupies two completely distinct blocks of physical memory.

$ perl -e '$foo = {}; fork; print "$$:$foo\n";'
18161:HASH(0x80fd254)
18162:HASH(0x80fd254)
$ perl -e 'fork; $foo = {}; print "$$:$foo\n";'
18163:HASH(0x80fd254)
18164:HASH(0x80fd254)

The effects are entirely expected. Perl takes up so much memory, and
that amount doesn't increase or decrease unless I recompile perl. So the
first allocation for a hash seems bound to occur at the same address in
virtual-memory every single time.

$ perl -e '$foo = {bar => 1};fork;print "$$:$foo" . $foo->{bar} . "\n";'

That works like you'd expect, doesn't it? Now consider this:

#!/usr/bin/perl
$foo = {};
if (fork == 0) {
	sleep(1);
} else {
	$foo->{bar} = 1;
}
print "$$:$foo:" . $foo->{bar} . "\n";'

All this serves to demonstrate is that the parent cannot modify the
child's memory map. While both exist in the same place in virtual
memory, the values obviously contain different values, and the physical
memory itself is different.

It's difficult to fully appreciate this in Perl... Maybe someone will
make a proper mmap() someday.



Re: Same $dbh under different pids?

Posted by Perrin Harkins <pe...@elem.com>.
harm wrote:

>On Wed, Oct 30, 2002 at 06:05:51PM +0800, Philippe M. Chiasson wrote:
>  
>
>>For the same reason that running this:
>>$> perl -e'fork; { $foo = {}; print "$$:$foo\n"}'
>>1984:HASH(0x804c00c)
>>1987:HASH(0x804c00c)
>>
>>produces this for me, every single time I run this program
>>
>>You are assuming that if (0x804c00c) is equal in different processes,
>>they must be pointers(or references, or handles) to the same thing. And
>>it is not the case ;-)
>>

Wait, ins't it the case?  That number is supposed to be the location in 
memory.  It seems like these are all pointing to the same hash.  I can't 
explain how that would happen though, based on the code shown here.

- Perrin




Re: Same $dbh under different pids?

Posted by harm <ha...@tty.nl>.
On Wed, Oct 30, 2002 at 06:05:51PM +0800, Philippe M. Chiasson wrote:
> For the same reason that running this:
> $> perl -e'fork; { $foo = {}; print "$$:$foo\n"}'
> 1984:HASH(0x804c00c)
> 1987:HASH(0x804c00c)
> 
> produces this for me, every single time I run this program
> 
> You are assuming that if (0x804c00c) is equal in different processes,
> they must be pointers(or references, or handles) to the same thing. And
> it is not the case ;-)

Ok, that was what I was looking for! Explains it all.

Thanks,
Harmen




-- 
                               The Moon is Waning Crescent (37% of Full)

Re: Same $dbh under different pids?

Posted by harm <ha...@tty.nl>.
On Tue, Oct 29, 2002 at 09:06:45PM +0000, Richard Clarke wrote:
> >Moi,
> >
> >a quick question: is it possible to have the 'same' dbh across the apache
> >children even if you do your best not to?
> >
> >This minimalistic handler:
> >use strict;
> >package Foo;
> >use Apache::DBI;
> >use DBI;
> >use Apache::Constants qw':common';
> >
> >my $dbh;
> >
> You haven't initialised this, so each request will get the same object 
> that is made below.
> 
> >$Apache::DBI::DEBUG = 1;
> >
> This should be in a start up file really.
> 
> >
> >sub handler {
> >  my $r = shift;
> >  $r->send_http_header;
> >  $r->print("ok");
> >
> You could just put,
>    print "ok";
> 
> >  $dbh ||= DBI->connect("dbi:mysql: ... etc);
> >
> Apache::DBI takes care of pooling connections.
> Use,
> 
>    my $dbh = DBI->connect(@CONNECT);
> 
> and get rid of the global $dbh above.

Richard,

thanks for your suggestions. The problem is not so much in the code (I know
the code above isn`t the 'best' way) but in the fact I seem to get the same
$dbh across children. I`m just curious if that is to be expected:

okdbh: Apache::DBI::db=HASH(0x8269a7c) (85799)
okdbh: Apache::DBI::db=HASH(0x8269a7c) (85800)
okdbh: Apache::DBI::db=HASH(0x8269a7c) (85801)
okdbh: Apache::DBI::db=HASH(0x8269a7c) (85802)
okdbh: Apache::DBI::db=HASH(0x8269a7c) (85803)
okdbh: Apache::DBI::db=HASH(0x8261424) (85799)
okdbh: Apache::DBI::db=HASH(0x8261424) (85800)

(Each line is a reload with the code after your suggestions)

Thanks,
Harmen

-- 
                               The Moon is Waning Crescent (37% of Full)

Re: Same $dbh under different pids?

Posted by Richard Clarke <ri...@likewhoa.com>.
harm wrote:

>Moi,
>
>a quick question: is it possible to have the 'same' dbh across the apache
>children even if you do your best not to?
>
>This minimalistic handler:
>use strict;
>package Foo;
>use Apache::DBI;
>use DBI;
>use Apache::Constants qw':common';
>
>my $dbh;
>
You haven't initialised this, so each request will get the same object 
that is made below.

>$Apache::DBI::DEBUG = 1;
>
This should be in a start up file really.

>
>sub handler {
>   my $r = shift;
>   $r->send_http_header;
>   $r->print("ok");
>
You could just put,
    print "ok";

>   $dbh ||= DBI->connect("dbi:mysql: ... etc);
>
Apache::DBI takes care of pooling connections.
Use,

    my $dbh = DBI->connect(@CONNECT);

and get rid of the global $dbh above.

Richard