linux进程间通信——共享内存
2016-03-12 21:26
453 查看
共享内存。linux进程之间通信的一种方式。先说说优缺点吧。
共享内存,顾名思义,就是一块内存,大家都可以用。
优点:操作方便。直接访问内存,效率高。不需要进程有父子关系等等
缺点:需要自己同步控制。
关于linux的任何函数都可以通过命令man order,查看相关帮助。想要仔细看这些函数的相关帮助,请亲自操作,这是最好的方法。
涉及的函数:
注:这一系列函数都是以shm开头(share memory)。
头文件 :
#include <sys/ipc.h>
#include <sys/shm.h>
1. int
shmget(key_t key, size_t size, int shmflg);
这个函数的功能就是用来分配要共享的内存。但是并不是分配好就能用的。要想使用,请看下一个函数。
参数:
key_t key :关键码,可以自己随意定义,一个关键码对应一块共享内存。其他地方要想获取这块内存,需要知道这个key。
size_t size:要共享的内存的大小。相当于我们malloc时的参数。
int shmflg :这个标志是权限,一般可以设置为 0666|IPC_CREAT.
返回值:
成功返回共享内存的id。
失败返回-1,同时会设置errno。
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
用来启动可分享的内存,并且把这段内存链接到本程序的地址空间中。
shm_id是由shmget函数返回的共享内存标识。
shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
shm_flg是一组标志位,通常为0。
成功返回可分享内存的首地址,失败返回(void*)-1;
3. int shmdt(const void *shmaddr);
用来取消分享内存与本程序的关联。并不是释放这段分享的内存空间。
成功返回0,失败返回-1。
4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
用来控制共享内存。
shm_id是shmget函数返回的共享内存标识符。
command是要采取的操作,它可以取下面的三个值 :
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段
buf是一个结构指针,它指向共享内存模式和访问权限的结构。
shmid_ds结构可以包括以下成员:
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
下面是一些代码。每隔1秒去设置一下共享内存的内容。
另一个进程,每隔1秒读取一下共享内存的内容。
同时运行两个程序。结果如图;
可以看出,由于没有同步控制。s1一开始输出了两个0。也是属于正常情况。这也是共享内存的缺点,需要我们自己同步。下一篇,学习信号量与共享内存同时使用。自己来同步。。
如有问题,请斧正。感激不尽。
谢谢!
共享内存,顾名思义,就是一块内存,大家都可以用。
优点:操作方便。直接访问内存,效率高。不需要进程有父子关系等等
缺点:需要自己同步控制。
关于linux的任何函数都可以通过命令man order,查看相关帮助。想要仔细看这些函数的相关帮助,请亲自操作,这是最好的方法。
涉及的函数:
注:这一系列函数都是以shm开头(share memory)。
头文件 :
#include <sys/ipc.h>
#include <sys/shm.h>
1. int
shmget(key_t key, size_t size, int shmflg);
这个函数的功能就是用来分配要共享的内存。但是并不是分配好就能用的。要想使用,请看下一个函数。
参数:
key_t key :关键码,可以自己随意定义,一个关键码对应一块共享内存。其他地方要想获取这块内存,需要知道这个key。
size_t size:要共享的内存的大小。相当于我们malloc时的参数。
int shmflg :这个标志是权限,一般可以设置为 0666|IPC_CREAT.
返回值:
成功返回共享内存的id。
失败返回-1,同时会设置errno。
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
用来启动可分享的内存,并且把这段内存链接到本程序的地址空间中。
shm_id是由shmget函数返回的共享内存标识。
shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
shm_flg是一组标志位,通常为0。
成功返回可分享内存的首地址,失败返回(void*)-1;
3. int shmdt(const void *shmaddr);
用来取消分享内存与本程序的关联。并不是释放这段分享的内存空间。
成功返回0,失败返回-1。
4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
用来控制共享内存。
shm_id是shmget函数返回的共享内存标识符。
command是要采取的操作,它可以取下面的三个值 :
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段
buf是一个结构指针,它指向共享内存模式和访问权限的结构。
shmid_ds结构可以包括以下成员:
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
下面是一些代码。每隔1秒去设置一下共享内存的内容。
<span style="font-size:14px;">#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <string.h> int main() { int shmid; void* mem; shmid = shmget(8889, 4, 0666|IPC_CREAT); if (shmid == -1) { printf("shmget err!\n"); return -1; } mem = shmat(shmid, 0, 0); if (mem == (void*)-1) { printf("shmat err!\n"); return -2; } int i=0; for (; i<20 ; i++) { *(int*)mem = i; printf("shm set:%d\n", i); sleep(1); } if (-1 == shmdt(mem)) { printf("shmdt err!\n"); return -3; } return 0; }</span>
另一个进程,每隔1秒读取一下共享内存的内容。
<span style="font-size:14px;">#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> int main() { int shmid ; void* mem; shmid = shmget(8889, 4, 0666|IPC_CREAT); if (shmid == -1) { printf("shmget err!\n"); return -1; } mem = shmat(shmid, 0, 0); if (mem == (void*)-1) { printf("shmat err!\n"); return -2; } int i = 0; for(;i<20;i++) { printf("shm:%d\n",*(int*)mem); sleep(1); } if (-1 == shmdt(mem)) { printf("shmdt err!\n"); return -3; } if (shmctl(shmid, IPC_RMID, 0) == -1) { printf("shmctl(shmid, IPC_RMID, 0) err!\n"); return -4; } return 0; }</span>
同时运行两个程序。结果如图;
可以看出,由于没有同步控制。s1一开始输出了两个0。也是属于正常情况。这也是共享内存的缺点,需要我们自己同步。下一篇,学习信号量与共享内存同时使用。自己来同步。。
如有问题,请斧正。感激不尽。
谢谢!
相关文章推荐
- Linux中用户和权限管理
- Beego安装 Mac linux
- Linux正则表达式语法
- 20135320赵瀚青LINUX内核分析第三周学习笔记
- Linux系统文件目录结构图
- Linux 用户及权限管理
- Linux中关机命令的区别
- Linux 设定定时任务crontab
- linux的自动任务创建
- linux及安全第三周总结——20135227黄晓妍
- 嵌入式linux交叉编译环境构建
- 误删ubuntu下/usr/bin
- linux下根据日期创建文件或者文件夹
- Linux文本处理工具三剑客之grep
- Linux条件变量的使用
- Linux vim环境设置
- Linux文本处理工具三剑客之grep
- Linux进程间通信(IPC)的几种方式
- Linux笔记(27)——用户切换与其他命令
- Linux下is not in the sudoers file解决方法