linux ipc 共享内存,linux ipc通信 - 共享内存

函数介绍

/* The following System V style IPC functions implement a shared memory

facility. The definition is found in XPG4.2. */

/* Shared memory control operation. */

int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf);

/* Get shared memory segment. */

int shmget (key_t __key, size_t __size, int __shmflg) ;

/* Attach shared memory segment. */

void *shmat (int __shmid, const void *__shmaddr, int __shmflg);

/* Detach shared memory segment. */

int shmdt (const void *__shmaddr) ;

shmget 说明

/* Get shared memory segment. */

int shmget (key_t __key, size_t __size, int __shmflg) ;

key shmget 中的key与shmid对应,可以用ftok来生成key或者指定IPC_PRIVATE

size 共享内存的大小

flag 权限设置

/* Mode bits for `msgget', `semget', and `shmget'. */

#define IPC_CREAT 01000 /* Create key if key does not exist. */

#define IPC_EXCL 02000 /* Fail if key exists. */

#define IPC_NOWAIT 04000 /* Return error on wait. */

后面3位是用户、用户组、其他用户的读写执行权限,如 0777

返回值 成功返回 shmid,用户后面的读写id,失败返回负数

shmctl 说明

/* Shared memory control operation. */

int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf);

shmid 通过shmget返回的id

cmd 控制选项

#define IPC_RMID 0 /* Remove identifier. */

#define IPC_SET 1 /* Set `ipc_perm' options. */

#define IPC_STAT 2 /* Get `ipc_perm' options. */

/* Commands for `shmctl'. */

#define SHM_LOCK 11 /* lock segment (root only) */

#define SHM_UNLOCK 12 /* unlock segment (root only) */

后面两个选项只适用于linux 和solaris

lock :当内存不够时不允许与外存换入换出

unlock 反之

buf set 和get的结构体信息,如可以通过get获取共享内存的大小

/* Data structure describing a shared memory segment. */

struct shmid_ds

{

struct ipc_perm shm_perm; /* operation permission struct */

size_t shm_segsz; /* size of segment in bytes */

__time_t shm_atime; /* time of last shmat() */

#ifndef __x86_64__

unsigned long int __glibc_reserved1;

#endif

__time_t shm_dtime; /* time of last shmdt() */

#ifndef __x86_64__

unsigned long int __glibc_reserved2;

#endif

__time_t shm_ctime; /* time of last change by shmctl() */

#ifndef __x86_64__

unsigned long int __glibc_reserved3;

#endif

__pid_t shm_cpid; /* pid of creator */

__pid_t shm_lpid; /* pid of last shmop */

shmatt_t shm_nattch; /* number of current attaches */

__syscall_ulong_t __glibc_reserved4;

__syscall_ulong_t __glibc_reserved5;

};

shmat说明

/* Attach shared memory segment. */

void *shmat (int __shmid, const void *__shmaddr, int __shmflg);

shmid 通过get返回的id

shmaddr 如何为空,则系统给你返回映射的地址,如果该参数非空,会映射到此地址上

为了不必要的麻烦,一般传递空

flag 在地址传递非空的时候用于设置SHM_RND, 好像是什么地址随机之类的

同样不用自找麻烦,传递0就完事了

代码展示

/**

* @file shm_lsw.c

* @author 李斯文 (lisiwen945@163.com)

* @brief 共享内存的接口测试函数

* @version 0.1

* @date 2021-01-28

*

* @copyright Copyright (c) 2021

*

*/

#include "apue.h"

#include

#include

#include

void shm_send()

{

int id = shmget(11, 1024, 0777);

if (id < 0) {

printf("%s shmget error errno %d\n", __func__, errno);

return;

} else {

printf("shmget success id %d\n", id);

}

struct shmid_ds ds;

if (shmctl(id, IPC_STAT, &ds) < 0) {

printf("func %s line %d error\n", __func__, __LINE__);

return;

} else {

printf("get share memory size %ld\n", ds.shm_segsz);

}

char * buf = shmat(id, 0, 0);

if (buf == NULL) {

printf("func %s line %d error\n", __func__, __LINE__);

return;

}

char msg[] = "lisiwen debug";

strcpy(buf, msg);

}

void shm_recv()

{

int id = shmget(11, 1024, 0777);

if (id < 0) {

printf("%s shmget error errno %d\n", __func__, errno);

return;

} else {

printf("shmget success id %d\n", id);

}

struct shmid_ds ds;

if (shmctl(id, IPC_STAT, &ds) < 0) {

printf("func %s line %d error\n", __func__, __LINE__);

return;

} else {

printf("get share memory size %ld\n", ds.shm_segsz);

}

char * buf = shmat(id, 0, 0);

printf("get msg %s\n", buf);

}

void shm_del()

{

int id = shmget(11, 1024, 0777);

if (id < 0) {

printf("%s shmget error errno %d\n", __func__, errno);

return;

} else {

printf("shmget success id %d\n", id);

}

if (shmctl(id, IPC_RMID, NULL) < 0) {

printf("func %s line %d error\n", __func__, __LINE__);

return;

} else {

printf("remove share memory %d success\n", id);

}

}

void shm_create()

{

int id = shmget(11, 1024, IPC_CREAT|IPC_EXCL|0777);

if (id < 0) {

printf("create shared memory error errno %d\n", errno);

} else {

printf("shmget success id %d\n", id);

}

}

int main(int argc, char *argv[])

{

if (argc < 2) {

printf("%s arg", argv[0]);

return 0;

}

if (strcmp(argv[1], "send") == 0) {

shm_send();

} else if (strcmp(argv[1], "recv") == 0) {

shm_recv();

} else if (strcmp(argv[1], "del") == 0) {

/* 使用ipcrm -q id也可以删除 */

shm_del();

} else if (strcmp(argv[1], "create") == 0) {

shm_create();

}

}

运行结果

ipcs 可以查看ipc的详细信息 -m表示共享内存

swing@ubun:~/code/apue.3e/ipc1$ ipcs -m

------------ 共享内存段 --------------

键 shmid 拥有者 权限 字节 连接数 状态

0x00000000 8 swing 600 67108864 2 目标

0x00000000 11 swing 600 524288 2 目标

0x00000000 12 swing 600 524288 2 目标

0x00000000 13 swing 600 524288 2 目标

0x00000000 20 swing 600 524288 2 目标

创建共享内存,可以看到多路一个id为23的内存,大小为1024字节

swing@ubun:~/code/apue.3e/ipc1$ ./shm_lsw create

shmget success id 23

swing@ubun:~/code/apue.3e/ipc1$ ipcs -m

------------ 共享内存段 --------------

键 shmid 拥有者 权限 字节 连接数 状态

0x00000000 8 swing 600 67108864 2 目标

0x00000000 11 swing 600 524288 2 目标

0x00000000 12 swing 600 524288 2 目标

0x00000000 13 swing 600 524288 2 目标

0x00000000 20 swing 600 524288 2 目标

0x0000000b 23 swing 777 1024 0

swing@ubun:~/code/apue.3e/ipc1$ ./shm_lsw send

shmget success id 23

get share memory size 1024

swing@ubun:~/code/apue.3e/ipc1$ ./shm_lsw recv

shmget success id 23

get share memory size 1024

get msg lisiwen debug

swing@ubun:~/code/apue.3e/ipc1$ ./shm_lsw del

shmget success id 23

remove share memory 23 success

swing@ubun:~/code/apue.3e/ipc1$ ipcs -m

------------ 共享内存段 --------------

键 shmid 拥有者 权限 字节 连接数 状态

0x00000000 8 swing 600 67108864 2 目标

0x00000000 11 swing 600 524288 2 目标

0x00000000 12 swing 600 524288 2 目标

0x00000000 13 swing 600 524288 2 目标

0x00000000 20 swing 600 524288 2 目标

swing@ubun:~/code/apue.3e/ipc1$

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值