Linux进程通信——使用共享内存

头文件:

#include <sys/ipc.h>

#include <sys/shm.h>

函数:shmget 分配共享内存
函数原型: int shmget(key_t key, size_t size, int shmflg);
key:键值,当为IPC_PRIVATE时新建一块共享内存;若为0时而shmflg中设了IPC_PRIVATE也将新建。
size:内存大小。
shmflg:标志。
IPC_CREAT:内存不存在则新建,否则打开;
IPC_EXCL:只有在内存不存在时才创建,否则出错。
返回:成功则返回标识符,出错返回-1

函数: void shmat(int shmid, char shmaddr, int shmflg);
shmid:通过shmget获取
shmaddr:映射到进程地址空间的起始地址,设为NULL将自动分配
shmflg:标志;SHM-RDONLY为只读,否则可读可写
返回:成功则返回内存起始地址,失败返回-1

函数: int shmdt(const void *shmaddr);
使共享内存区脱离映射的进程的地址空间
返回:成功返回0,错误返回-1

函数: void shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid:通过shmget获取
cmd:控制命令,如下:
IPC_STAT:获取内存状态
IPC_SET:改变内存状态
IPC_RMID:删除内存
buf:结构体指针,用于存放共享内存状态
返回:成功返回0,错误返回-1

注意:共享内存一旦创建就会一直存在系统中,直到手动删除或者重启系统。
例子:

/**************************************
 *
 * 使用共享内存进行进程通信
 * 龙昌博客:http://www.xefan.com
 *
**************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage:%s str\n", argv[0]);
        exit(1);
    }
    int shmid;
    char *p_addr, *c_addr;
    //创建共享内存
    if ((shmid=shmget(IPC_PRIVATE, 1024, IPC_CREAT)) == -1)
    {
        perror("shmget");
        exit(errno);
    }
    if(fork() > 0)    //父进程向内存写入数据
    {
        //获取内存起始地址
    p_addr = shmat(shmid, 0, 0);
        memset(p_addr, 0, 1024);
    //向内存中写入数据
        strncpy(p_addr, argv[1], 1024);
        shmdt(p_addr);
        sleep(3);
        wait(0);
    }
    else        //子进程从内存中读取数据
    {
        //获取内存起始地址
        c_addr = shmat(shmid, 0, 0);
        sleep(4);
        printf("child get %s\n", c_addr);
        shmdt(c_addr);
    }
    //删除共享内存
    if (shmctl(shmid, IPC_RMID, NULL) < 0)
    {
        perror("shmctl");
        exit(1);
    }
    return 0;
}