glasswalk3r has asked for the wisdom of the Perl Monks concerning the following question:
Update
I got this excerpt from the book Pro Perl while searching with Google:
"This includes nested data structures and objects, making shared memory ties potentially very powerful. However, each reference becomes a new shared memory object, so a complex structure can quickly exceed the system limit on shared memory segments."
Here is the URL for it: http://books.google.com.br/books?id=1bbjLxkBLaMC&pg=PA888&lpg=PA888&dq=perl+ipc+shared+memory&source=bl&ots=GfhUOuXJND&sig=t1DqzIFeFCneihcnuK43r76mk4Y&hl=pt-BR&ei=9ZnBTM7-LMX_lgeg5fiyCg&sa=X&oi=book_result&ct=result&resnum=5&ved=0CCgQ6AEwBDgU#v=onepage&q=perl%20ipc%20shared%20memory&f=false. I think this explains enough.
Greetings monks,
I'm doing some testing with IPC shared memory by using IPC::Shareable with the code below (borrowed from a O'Reilly's book):
#!/usr/bin/perl # sharetest - test shared variables across forks use strict; use warnings; use IPC::Shareable; my %buffer; my $handle = tie %buffer, 'IPC::Shareable', undef, { destroy => 1 }; $buffer{test} = "inoangrnglkdtghnlkhnl"; $buffer{test1} = "inoangrnglkdtghnlkhnl"; $buffer{test2} = "inoangrnglkdtghnlkhnl"; $buffer{test3} = "inoangrnglkdtghnlkhnl"; $buffer{test4} = "inoangrnglkdtghnlkhnl"; $SIG{INT} = sub { die "$$ dying\n" }; my @kids; for ( 1 .. 10 ) { my $child; unless ( $child = fork ) { # i'm the child die "cannot fork: $!" unless defined $child; squabble(); exit; } push @kids, $child; # in case we care about their pids } while (1) { print "Buffer is $buffer{test}\n"; sleep 1; } die "Not reached"; sub squabble { my $i = 0; while (1) { next if $buffer{test} =~ /^$$\b/o; $handle->shlock(); $i++; $buffer{test} = "$$ $i"; $handle->shunlock(); } }
After running the code, I got the following output from ipcs -m command in a shell:
- Segmentos da memória compartilhada - chave shmid proprietário perms bytes nattch st +atus 0x00000000 0 root 777 102400 1 + 0x00000000 196609 jackal 600 393216 2 dest + 0x00000000 229378 jackal 600 393216 2 dest + 0x00000000 262147 jackal 600 393216 2 dest + 0x00000000 294916 jackal 600 393216 2 dest + 0x00000000 327685 jackal 600 393216 2 dest + 0x00000000 360454 jackal 600 393216 2 dest + 0x00000000 393223 jackal 600 393216 2 dest + 0x00000000 425992 jackal 600 393216 2 dest + 0x00000000 458761 jackal 600 393216 2 dest + 0x00000000 491530 jackal 600 393216 2 dest + 0x00000000 524299 jackal 600 393216 2 dest + 0x00000000 557068 jackal 600 393216 2 dest + 0x00000000 589837 jackal 600 393216 2 dest + 0x00000000 655374 jackal 600 393216 2 dest + 0x00000000 688143 jackal 600 393216 2 dest + 0x00000000 1114128 jackal 600 393216 2 dest + 0x00000000 1146897 jackal 600 393216 2 dest + 0x00000000 851986 jackal 600 393216 2 dest + 0x00000000 983059 jackal 600 393216 2 dest + 0x00000000 1015828 jackal 600 393216 2 dest + 0x00000000 1212437 jackal 666 65536 1
The line regarding the created shared segment by the program is the last one.I think this is quite expected.
BUT if I change the program to use a array reference instead of a scalar as a value for each key:
$buffer{test} = "inoangrnglkdtghnlkhnl"; $buffer{test1} = [ 'one', 'two' ]; $buffer{test2} = [ 'one', 'two' ]; $buffer{test3} = [ 'one', 'two' ]; $buffer{test4} = [ 'one', 'two' ];
I got a different amount of segments created:
- Segmentos da memória compartilhada - chave shmid proprietário perms bytes nattch st +atus 0x00000000 0 root 777 102400 1 + 0x00000000 196609 jackal 600 393216 2 dest + 0x00000000 229378 jackal 600 393216 2 dest + 0x00000000 262147 jackal 600 393216 2 dest + 0x00000000 294916 jackal 600 393216 2 dest + 0x00000000 327685 jackal 600 393216 2 dest + 0x00000000 360454 jackal 600 393216 2 dest + 0x00000000 393223 jackal 600 393216 2 dest + 0x00000000 425992 jackal 600 393216 2 dest + 0x00000000 458761 jackal 600 393216 2 dest + 0x00000000 491530 jackal 600 393216 2 dest + 0x00000000 524299 jackal 600 393216 2 dest + 0x00000000 557068 jackal 600 393216 2 dest + 0x00000000 589837 jackal 600 393216 2 dest + 0x00000000 655374 jackal 600 393216 2 dest + 0x00000000 688143 jackal 600 393216 2 dest + 0x00000000 1114128 jackal 600 393216 2 dest + 0x00000000 1146897 jackal 600 393216 2 dest + 0x00000000 851986 jackal 600 393216 2 dest + 0x00000000 983059 jackal 600 393216 2 dest + 0x00000000 1015828 jackal 600 393216 2 dest + 0x00000000 1474581 jackal 666 65536 1 + 0x00000000 1277974 jackal 600 393216 2 dest + 0x00000000 1507351 jackal 666 65536 0 + 0x00000000 1540120 jackal 666 65536 0 + 0x00000000 1572889 jackal 666 65536 0 + 0x00000000 1605658 jackal 666 65536 0
All segments created by the perl script have the size equal to 65536. Since the hash is being serialized with Storable, I would expect to see just one segment, but the script created four more.
Is this a behavior of IPC::Shareable or something related to the how IPC shared memory works?
Thank you in advance,
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Using complex data with IPC::Shareable
by BrowserUk (Patriarch) on Oct 22, 2010 at 03:04 UTC | |
by glasswalk3r (Friar) on Oct 22, 2010 at 13:05 UTC | |
by BrowserUk (Patriarch) on Oct 23, 2010 at 00:09 UTC |