PHP: shm_attach - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

shm_detach sem_remove

Last updated: Fri, 26 Jan 2007

view this page in

# shm_attach

(PHP 3 >= 3.0.6, PHP 4, PHP 5)

shm_attach -- Creates or open a shared memory segment

## Description

int shm_attach ( int key [, int memsize [, int perm]] )

shm_attach() returns an id that can be used to access the System V shared memory with the given key, the first call creates the shared memory segment with `memsize` (default: sysvshm.init_mem in the `php.ini`, otherwise 10000 bytes) and the optional perm-bits `perm` (default: 0666).

A second call to shm_attach() for the same `key` will return a different shared memory identifier, but both identifiers access the same underlying shared memory. `Memsize` and `perm` will be ignored.

See also ftok(), and shm_detach().

add a note User Contributed Notes
shm_attach
Uther Pendragon
08-Mar-2007 09:08
`As a follow-up to my last post regarding shm_attach and its limit capability for knowing how it was created....
for more control, use the shmop_* series of functions, as they have finer grained control than these.
and by the way: the SHMOP functions SHOULD BE listed under "see also" for all the SHM* wrapper functions (I assume they are wrappers to the SHMOP* functions).`
Uther Pendragon
24-Jan-2007 08:26
`Since there aren't seperate functions for CREATING and ATTACHING shared memory (a mistake in my opinion), you might want to do some testing to check whether you've created it or not, as you may not want the slave of a master/slave pair to ever create the shared memory.
One way you can test this is by having your slave set the size to something small, then testing the size by putting a variable too large to fit, e.g.:
function get_shmem() {
return shm_attach(ftok('somefile.txt', 'T'), 100, 0644);
}
$shm = get_shmem();
while (!@shm_put_var($shm, 1, str_repeat('.....', 20))) {
shm_remove($shm);
sleep(1);
//we created it, so we'll remove it and sleep to wait for the master to create it, then try again.
$shm = get_shmem();
}
shm_remove_var($shm, 1);
//here we know the shared memory was already created, because we could put a variable in bigger than the size requested.
Another way you can handle it is to have all programs initialize the shared memory with the same parameters... I had a problem with this when my clients starting too fast and created the shmem without passing a memsize value, so it was defaulting to 10k which was too small.`
Katzenmeier
04-Nov-2006 03:36
`The limit for one SHM block seems to be 32 MB, but you can split your data in several SHM blocks if you need to. The total SHM limit seems to be about 8 GB.
I'm not sure whether this is true for all configurations.`
muytoloco at yahoo dot com dot br
23-Feb-2006 09:33
`If one process make a shm_attach to one inexistent memory area, this area will be created under the same priviliegies of the script running user. If another process will try to create or acces the same area, runnig by other user with different privileges of the first user, an error will occur.`
rch at todo dot com dot uy
28-Mar-2005 04:17
`Cecil, the key of a var is an integer (not the name ). You can put multiples vars in the same share.
#!/usr/local/bin/php -q
<?PHP
$SHM_KEY = ftok(__FILE__, chr( 4 ) );
$data = shm_attach($SHM_KEY, 1024, 0666);
$test1 = array("hello","world","1","2","3");
$test2 = array("hello","world","4","5","6");
$test3 = array("hello","world","7","8","9");
shm_put_var($data, 1, $test1);
shm_put_var($data, 2,$test2);
shm_put_var($data, 3,$test3);
print_r(shm_get_var($data, 1));
print_r(shm_get_var($data, 2));
print_r(shm_get_var($data, 3));
shm_detach($data);
?>`
andreyKEINSPAM at php dot net
24-Apr-2004 09:31
`As far as I see from the sources of ext/sysvshm, it's not needed to do arithmetic (bit) OR (|) of "perm" with IPC_CREAT (and IPC_EXCL). The extension will do it for you. It tries to attach to the memory segment and if the try did not succeed it tries to attach but with flags set to user_flag | IPC_CREAT | IPC_EXCL.
The exact code (shm_flag is the third param to the function) :
if ((shm_id = shmget(shm_key, 0, 0)) < 0) {
if (shm_size < sizeof(sysvshm_chunk_head)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x: memorysize too small", shm_key);
efree(shm_list_ptr);
RETURN_FALSE;
}
if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 0x%x: %s", shm_key, strerror(errno));
efree(shm_list_ptr);
RETURN_FALSE;
}
}`
Cecil
18-Mar-2004 12:37
`Here is an example of how to use one shared memory block to store multiple variables or arrays.. unfortunetly in order to store more than ONE variable, you have to use sem_get() multiple times.. same goes for shm_attach(), shm_put_var() and shm_get_var()
#!/usr/local/bin/php -q
<?PHP
// test.php
$SHM_KEY = ftok(__FILE__,'A');
$shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$shmid2 = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$shmid3 = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$data = shm_attach($shmid, 1024);
$data2 = shm_attach($shmid2, 1024);
$data3 = shm_attach($shmid3, 1024);
$test = array("hello","world","1","2","3");
$test2 = array("hello","world","4","5","6");
$test3 = array("hello","world","7","8","9");
shm_put_var($data,$inmem,$test);
shm_put_var($data2,$inmem2,$test2);
shm_put_var($data3,$inmem3,$test3);
print_r(shm_get_var($data,$inmem));
print_r(shm_get_var($data2,$inmem2));
print_r(shm_get_var($data3,$inmem3));
shm_detach($data);
shm_detach($data2);
shm_detach($data2);
?>
to REALLY test it.. create a second script like so and run it..
#!/usr/local/bin/php -q
<?PHP
// test2.php
$SHM_KEY = ftok(__FILE__,'A');
$shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$shmid2 = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$shmid3 = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$data = shm_attach($shmid, 1024);
$data2 = shm_attach($shmid2, 1024);
$data3 = shm_attach($shmid3, 1024);
print_r(shm_get_var($data,$inmem));
print_r(shm_get_var($data2,$inmem2));
print_r(shm_get_var($data3,$inmem3));
shm_detach($data);
shm_detach($data2);
shm_detach($data2);
?>
As you can see, test2.php doesn't insert anything into shared memory.. yet it pulls out 3 totally different arrays already stored..
Hope that helps.. took me a bit to get it right.. everyone seems to have their own idea of how shm should be used. lol.
BTW, not sure how the ftok works to be honest, cause I didn't change the __FILE__ to match the file path of test.php or anything.. I would think that the file path out have to be the exact same to work correctly.. oh well, it worked as-is! haha..
- Cecil`
php at cytrax dot de
18-Jan-2002 08:36
`The memsize needed for shared memory (tested on linux system) can be calculated with:
For each varialbe you want to store: 24 Bytes
+ serialized var-size (see below) alligned by 4 Bytes
+ 16 Bytes
For a update of a var with the same key, the memory for the old var will be needed extra.`
koester at x-itec dot de
21-Mar-2001 12:41
`4194304 means 4 MB and NOT 4 GB for shared memory on FreeBSD. You can increase the shared memory at runtime if you like.`
lew at persiankitty dot com
25-Jan-2001 04:30
`Finding out shared memory kernel settings in FreeBSD:
sys1# sysctl -a | grep -i SHM
kern.ipc.shmmax: 4194304
kern.ipc.shmmin: 1
kern.ipc.shmmni: 96
kern.ipc.shmseg: 64
kern.ipc.shmall: 1024
kern.ipc.shm_use_phys: 0
Shows us that we can allocate a total of 4GB (wow) of shared memory, etc...`
webmaster at mail dot communityconnect dot com
10-Sep-1999 01:50
`With Sun Solaris 2.x, the MAXIMUM shared memory value allowed is 1,048,576. The maximum allowed value can be determined using the command /usr/sbin/sysdef. On Linux, there does not seem to be any system enforced maximum size. To change the maximum allowed size on Solaris 2.x, use set shmsys:shminfo_shmmax=[new value].`
h dot raaf at i-k-c dot net
25-Mar-1999 05:40
`Notice that 'int key' for shared-memory is shared with the keys used for semaphores. So you get in trouble when you use the same key value for semaphores and shared memory!`
eric at superstats dot com
12-Feb-1999 07:04
`Objects are stored serialized in shm_put_var, so to find a value for memsize, you can use strlen(serialize($object_to_store_in_shm)).`
add a note
shm_detach sem_remove

Last updated: Fri, 26 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 10:36:09 2007 PST