|
I'm using IPC::Shareable module in my software, and I discovered
strange behavior of it under certain conditions.
Conditions:
1. Main program must for at least 2 times
2. Both main parent, child1 and child2 must modify shared variable
3. New value of shared variable must be reference (not scalar)
Under these conditions the second child process that want to modify
shared variable terminates with:
IPC::Shareable::SharedMem: shmget: File exists
at /usr/share/perl5/IPC/Shareable.pm line 566
Could not create shared memory segment: File exists
If we try to assign simple value (scalar) in second child everything works fine,
the problem doesn't exist also if we do not modify shared value erlier in parent
or in child 1.
Size, Exclusive, Create parameters have no influence on program's behavior.
Effective uid or gid have no influence on program's behavior.
My system configuration is:
Linux kubuntu 2.6.17-10-generic
perl5 (revision 5 version 8 subversion 8)
IPC::Shareable version 0.60
Shared mem settings:
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 196608
max total shared memory (pages) = 201326592
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
------ Messages: Limits --------
max queues system wide = 16
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384
Here is a proof of concept simple code:
#!/usr/bin/perl -W
use strict;
use IPC::Shareable qw( :lock);
my $shm;
my $data = {};
warn "1. shmem init\n";
unless ($shm = tie $data, 'IPC::Shareable','serv', {'create', 1, 'exclusive', 1, 'destroy', 1 } ) {
die "Can't initialize shared memory ($!)";
}
warn "2. parent sets value\n";
$shm->shlock(LOCK_EX);
$data->{'new'} = {'3' => '3la', 'up3' => '33blele'};
$shm->shunlock(LOCK_EX);
warn "3. parent forks and sleep 1\n";
my $pid = fork;
if ($pid) { # parent
sleep 1;
}
else { # child
warn "4. child 1 sets value\n";
$shm->shlock(LOCK_EX);
$data->{'new'} = {'1' => 'ala', 'up' => 'blele'};
$shm->shunlock(LOCK_EX);
exit;
}
warn "5. parent forks second time and sleep 3\n";
$pid = fork;
if ($pid) { # parent
sleep 3;
}
else { # child 2
warn "6. child 2 sets value\n";
$shm->shlock(LOCK_EX);
$data->{'new'} = {'41' => 'al4a', '4up' => 'b4lele'};
$shm->shunlock(LOCK_EX);
exit;
}
Best Regards,
Tom
|