Share memory provides a convience way to let different processes to communicate each other. It's easy to use, however, sometime, permission issue pops up like below

IPC::Shareable::SharedMem: shmget: Permission denied
 at /usr/lib/perl5/site_perl/5.8.3/IPC/Shareable.pm line 566
Could not create shared memory segment:
 at test_shareable.pl line 5

How to identify and resolve the problem?

1. Understand how a share memory segment is identified and shared with other processes

Perl IPC::Shareable allows you to tie a variable to shared memory making it easy to share the contents of that variable with other Perl processes. The association between variables in distinct processes is provided by GLUE. This is an integer number or 4 character string that serves as a common identifier for data across process space. Hence the statement

 tie $scalar, 'IPC::Shareable', 'data';

in program one and the statement

 tie $variable, 'IPC::Shareable', 'data';

in program two will bind $scalar in program one and $variable in program two.

The GLUE is an associat variable used as the KEY argument in subsequent calls to shmget() and semget().

You may noticed that tie function can pass a hash option reference to Perl IPC::Shareable, in that case, you can use the field named key in the hash for the value of GLUE. So

 tie $variable, 'IPC::Shareable', 'data', \%options;

is equivalent to

 tie $variable, 'IPC::Shareable', { key => 'data', ... };

The default value is IPC_PRIVATE, meaning that your variables cannot be shared with other processes.

 

So, Things are getting clear, Perl Shareable permission problem mostly happens when

1. A program was ran by another user(mostly root) before and did not clean the shareable variable.
2. Another program which is run by other user is using the same GLUE.

Note: If GLUE is longer than 4 characters, only the 4 most significant characters are used. These characters are turned into integers by unpack()ing them. If GLUE is less than 4 characters, it is space padded.

2. Identify which program is using and holding the shareable memory.

Using ipcs, ipcs -m returns shared memory segment info

# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x0052e2c1 983040     postgres   600        48         33                      

ipcs -mp shows which PID is using(or used) the share memory segment

# ipcs -mp

------ Shared Memory Creator/Last-op --------
shmid      owner      cpid       lpid      
983040     postgres   4488       5403      

cpid: the pid currently using the share memory segment

lpid: last pid used this share memory segment

Then, search the pid info

# ps -p 4488
  PID TTY          TIME CMD
 4488 ?        00:01:02 postmaster
# ps -p 5403
  PID TTY          TIME CMD

ipcs -mt shows when the shared memory segment was attached/detached/changed

# ipcs -mt

------ Shared Memory Attach/Detach/Change Times --------
shmid      owner      attached             detached             changed             
983040     postgres   Mar  2 12:20:56      Mar  2 12:20:56      Feb 18 21:45:29  

3. Clear the shareable memory by perl

IPC::Shareable provides three methods to remove shared memory segment

 remove(), clean_up(), and clean_up_all()

and the destroy option to tie() to remove shared memory segment

Calling remove() on the object underlying a tie()d variable removes the associated shared memory segment

 (tied VARIABLE)->remove;

To remove all shared memory segments created by the process

 IPC::Shareable->clean_up;

To remove all shared memory segments encountered by the process. Segments are removed even if they were not created by the calling process

 IPC::Shareable->clean_up_all;

Specifying the destroy option when tie()ing a variable coerces IPC::Shareable to remove the underlying shared memory segment when the process calling tie() exits gracefully. Note that any related shared memory segments created automagically by the use of references will also be removed.

Look this shared memory

 tie $variable, 'IPC::Shareable', 'data' \%options;

where:
create => 1, exclusive => 0, destroy => 1, mode => 0, size => IPC::Shareable::SHM_BUFSIZ()

The field destroy is set to '1', then untie function will remove the shared memory segmen

4. Clear the shareable memory by system level

 Use ipcrm, it is also recommended to use ipcrm to clear out shared memory segment if you experience perl IPC::Shareable buggy thing.

ipcrm -m <shmid>

5. Make sure different programs are not using the same share memory key

 Same to the Note in the #1,

If GLUE is longer than 4 characters, only the 4 most significant characters are used. These characters are turned into integers by unpack()ing them. If GLUE is less than 4 characters, it is space padded.

The following two shareable variable are tied to one shared memory segment.

 tie $variable, 'IPC::Shareable', 'data_a' \%options;
tie $variable, 'IPC::Shareable', 'data_b' \%options;

 See more in Perl Shareable Memory examples

Comments powered by CComment