XSI IPC之共享内存 (1)

2019-03-28  本文已影响0人  静倚晴窗笑此生

有两种方法创建共享内存,第一种用shmop提供的函数,第二种通过mmap(2)函数

man shmop 查看共享内存操作函数

shmget( )

获得一个共享存储标识符

函数声明

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

参数含义

第一个参数为ftok(3)函数返回值,如果 key值为 IPC_PRIVATE 则只能用于有亲缘关系

第二个参数为共享内存空间的大小

第三个参数可选(多选用或运算)

IPC_CREAT 创建,需要或上文件权限

IPC_EXCLIPC_CREAT一起使用,确保如果消息队列已经创建,则返回失败

返回值

成功返回 共享内存示例

失败返回 -1 并且设置errno 如果标识符使用了IPC_CREATIPC_EXCL 并且errno的值为EEXIST,代表消息队列已经存在

shmat()

挂载共享内存,将共享内存连接到进程的可用地址上

函数声明

#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

参数含义

第一个参数为共享内存示例

第二个参数如果是NULL,则内核自动分配到进程所在的第一个可用地址上,不传NULL,则分配地址由用户指定;

返回值

成功返回共享内存地址,失败返回-1,设置errno值

shmdt()

卸载共享内存,将共享内存从进程的可用地址上删除

函数声明

#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);

参数含义

shmaddr为shmdt函数的返回值

shmctl()

移除共享内存

函数声明

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

共享内存示例1

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(void)
{
    pid_t pid;
    int shmid;
    int flag = 1;

    shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | IPC_EXCL | 0600);
    if (shmid < 0) {
        if (errno == EEXIST) {
            shmid = shmget(IPC_PRIVATE, 1024, 0);
            flag = 0;
        } else {
            perror("shmid()");
            exit(1);
        }
    }

    pid = fork();
    if (pid < 0) {
        perror("fork()");
        goto FORK_ERROR;
    }

    if (pid == 0) {
        void *p = shmat(shmid, NULL, 0);    
        memcpy(p, "hello world", 11);
        shmdt(p);
        exit(1);
    }

    wait(NULL);
    void *ptr = shmat(shmid, NULL, 0);
    puts((char *)ptr);
    shmdt(ptr);

    if (flag)
        shmctl(shmid, IPC_RMID, NULL);
    exit(0);
FORK_ERROR:
    if (flag)
        shmctl(shmid, IPC_RMID, NULL);
    exit(1);
}
上一篇下一篇

猜你喜欢

热点阅读