Advanced Programming in UNIX Environment Episode 93

The address in the calling process at which the segment is attached depends on the addr argument and whether the SHM_RND bit is specified in flag.

  • If addr is 0, the segment is attached at the first available address selected by the kernel. This is the recommended technique.
  • If addr is nonzero and SHM_RND is not specified, the segment is attached at the address given by addr.
  • If addr is nonzero and SHM_RND is specified, the segment is attached at the address given by (addr − (addr modulus SHMLBA)). The SHM_RND command stands for ‘round.’ SHMLBA stands for 'low boundary address multiple’ and is always a power of 2. What the arithmetic does is round the address down to the next multiple of SHMLBA.

The identifier remains in existence until some process (often a server) specifically removes it by calling shmctl with a command of IPC_RMID.

#include 
int shmdt(const void *addr);

The addr argument is the value that was returned by a previous call to shmat. If successful, shmdt will decrement the shm_nattch counter in the associated shmid_ds structure.

#include "apue.h"
#include 

#define ARRAY_SIZE 40000
#define MALLOC_SIZE 100000
#define SHM_SIZE 100000
#define SHM_MORE 0600

char array[ARRAY_SIZE];

int main(void)
{
    int shmid;
    char *ptr, *shmptr;

    printf("array[] from %p to %p\n", (void *)&array[0],
        (void *)&array[ARRAY_SIZE]);
    printf("stack around %p\n",(void *)&shmid);

    if((ptr=malloc(MALLOC_SIZE))==NULL)
        err_sys("malloc error");
    printf("malloced from %p to %p\n", (void *)ptr,
        (void *)ptr+MALLOC_SIZE);

    if((shmid=shmget(IPC_PRIVATE,SHM_SIZE,SHM_MORE))<0)
        err_sys("shmget error");
    if((shmptr=shmat(shmid, 0, 0))==(void *)-1)
        err_sys("shmat error");
    printf("shared memory attached from %p to %p\n"< (void *)shmptr,
        (void *)shmptr+SHM_SIZE);

    if(shmctl(shmid, IPC_RMID,0)<0)
        err_sys("shmctl error");

    return 0;
}

Print where various types of data are stored

Shared memory can be used between unrelated processes. But if the processes are related, some implementations provide a different technique.

The following technique works on FreeBSD 8.0, Linux 3.2.0, and Solaris 10. Mac OS X 10.6.8 currently doesn’t support the mapping of character devices into the address space of a process.

The device /dev/zero is an infinite source of 0 bytes when read. This device also accepts any data that is written to it, ignoring the data. Our interest in this device for IPC arises from its special properties when it is memory mapped.

  • An unnamed memory region is created whose size is the second argument to mmap, rounded up to the nearest page size on the system.
  • The memory region is initialized to 0.
  • Multiple processes can share this region if a common ancestor specifies the MAP_SHARED flag to mmap.
这里写代码片

IPC between parent and child using memory mapped I/O of /dev/zero

你可能感兴趣的:(Advanced,Programming,in,the,Unix,Environment)