进程通信----共享内存以及mmap函数实现共享内存
2016-10-25 14:02
537 查看
进程间通信----共享内存
最底层的原理:让不同的进程看到相同的物理资源(将不同进程的 虚拟内存地址 映射到 同一块相同的物理内存上)
对共享内存的操作没有进行检测 PV操作需要用户自己来完成
对共享内存的操作 执行向上取整 按页申请 (如一页不够就用两页 但用户可以使用的 还是他自己申请的那么大 如申请4097B 实际申请8kB 但用户只能用4097B【一页4096B】)
生命周期随内核 不随进程(进程退出 进程不主动删除 共享内存 则共享内存还在)
1、用到的函数
int shmget(key_t key, size_t size, int shmflg); 【创建共享内存 | 获得共享内存】
key: 由ftok()函数返回的标识符
size:字节为单位所需的共享内存容量
shmflg:IPC_CREAT
IPC_EXCL
IPC_CREAT|IPC_EXCL
IPC_CREAT|IPC_EXCL|0666
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
[ 控制共享内存]
shm_id:shmget返回的共享内存标识符
cmd:
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即把共享内存的当前设置值保存在shmid_ds中。
IPC_SET:如果进程有足够权限,把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID :删除共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
at是attach
[挂接*(将创建的共享内存与进程的虚拟内存相关联 让进程可以向操作malloc的空间一样操作共享内存) 使得ipcs -m 中nattch选项加1]
返回值可以理解为(当成)malloc申请的资源地址 【其实两个是完全不一样的】
成功返回指向共享内存的指针,失败返回-1
const void *shmaddr在哪开辟 可以让系统自己决定(NULL)
int shmflg 开辟的属性读写权限 可以让系统自己决定(NULL)
int shmdt(const void *shmaddr);
dt是detach[删除挂接 使得ipcs -m 中nattch选项减去1]
注意: 对共享内存的操作没有进行 先后顺序检测 任何进程都可以操作 要实现互斥 就要自己用信号量进行加锁的 PV操作
2、查看的命令:
ipcs -m
写一个监视的脚本
while :; do ipcs -m|grep "root"; sleep 1; echo "###########"; done
3、练习程序
------------------------------shm.h--------------------------------------
监视脚本:[root@localhost bozi]# while :; do ipcs -m | grep root; sleep 1;echo "##########";done
0xd200649e 1802257 root 666 4096 0
##########
0xd200649e 1802257 root 666 4096 0
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 2
##########
0xd200649e 1802257 root 666 4096 2
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 0 首先由父进程创建共享内存,父进程创建子进程,父子进程都关联了共享内存,关联的个数由0变为2,因父进程休息时间短,取消关联,关联个数变为1,最后子进程也取消关联,关联个数变为0,最后将共享内存销毁。
4、mmap函数
http://baike.baidu.com/link?url=GW7f3zIQ2_5TJEhowcqp8ABwpt45EqZaEZIJpfRxRsvjoXne8790ebjZ4sDQ6g-J2DFqy3gk3tnI6UsNoUIRwq
mmap将一个文件或者其他对象映射进内存。mmap也可以实现共享内存。mmap函数调用使得进程之间通过映射同一个文件实现共享内存。文件被映射到进程地址空间后,进程可以像读写内存一样对文件进行操作。
函数:
[code=cpp;toolbar:false"> #include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
void *mmap64(void *addr, size_t length, int prot, int flags,int fd, off64_t offset);
int munmap(void *addr, size_t length);
最底层的原理:让不同的进程看到相同的物理资源(将不同进程的 虚拟内存地址 映射到 同一块相同的物理内存上)
对共享内存的操作没有进行检测 PV操作需要用户自己来完成
对共享内存的操作 执行向上取整 按页申请 (如一页不够就用两页 但用户可以使用的 还是他自己申请的那么大 如申请4097B 实际申请8kB 但用户只能用4097B【一页4096B】)
生命周期随内核 不随进程(进程退出 进程不主动删除 共享内存 则共享内存还在)
1、用到的函数
int shmget(key_t key, size_t size, int shmflg); 【创建共享内存 | 获得共享内存】
key: 由ftok()函数返回的标识符
size:字节为单位所需的共享内存容量
shmflg:IPC_CREAT
IPC_EXCL
IPC_CREAT|IPC_EXCL
IPC_CREAT|IPC_EXCL|0666
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
[ 控制共享内存]
shm_id:shmget返回的共享内存标识符
cmd:
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即把共享内存的当前设置值保存在shmid_ds中。
IPC_SET:如果进程有足够权限,把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID :删除共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
at是attach
[挂接*(将创建的共享内存与进程的虚拟内存相关联 让进程可以向操作malloc的空间一样操作共享内存) 使得ipcs -m 中nattch选项加1]
返回值可以理解为(当成)malloc申请的资源地址 【其实两个是完全不一样的】
成功返回指向共享内存的指针,失败返回-1
const void *shmaddr在哪开辟 可以让系统自己决定(NULL)
int shmflg 开辟的属性读写权限 可以让系统自己决定(NULL)
int shmdt(const void *shmaddr);
dt是detach[删除挂接 使得ipcs -m 中nattch选项减去1]
注意: 对共享内存的操作没有进行 先后顺序检测 任何进程都可以操作 要实现互斥 就要自己用信号量进行加锁的 PV操作
2、查看的命令:
ipcs -m
写一个监视的脚本
while :; do ipcs -m|grep "root"; sleep 1; echo "###########"; done
3、练习程序
------------------------------shm.h--------------------------------------
= 'X';-------------------------------------运行截图---------------------------------
i++;
}
buf[4095] = '\0';
sleep(3);
delete_shm(buf);
sleep(3);
}
else
{
// father
sleep(4);
char* buf = at_shm(shm_id);
sleep(2);
printf("%s\n", buf);
delete_shm(buf);
sleep(2);
//waitpid(id, NULL, 0);
wait(NULL);
rm_shm(shm_id);
}
return 0;
}
监视脚本:[root@localhost bozi]# while :; do ipcs -m | grep root; sleep 1;echo "##########";done
0xd200649e 1802257 root 666 4096 0
##########
0xd200649e 1802257 root 666 4096 0
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 2
##########
0xd200649e 1802257 root 666 4096 2
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 1
##########
0xd200649e 1802257 root 666 4096 0 首先由父进程创建共享内存,父进程创建子进程,父子进程都关联了共享内存,关联的个数由0变为2,因父进程休息时间短,取消关联,关联个数变为1,最后子进程也取消关联,关联个数变为0,最后将共享内存销毁。
4、mmap函数
http://baike.baidu.com/link?url=GW7f3zIQ2_5TJEhowcqp8ABwpt45EqZaEZIJpfRxRsvjoXne8790ebjZ4sDQ6g-J2DFqy3gk3tnI6UsNoUIRwq
mmap将一个文件或者其他对象映射进内存。mmap也可以实现共享内存。mmap函数调用使得进程之间通过映射同一个文件实现共享内存。文件被映射到进程地址空间后,进程可以像读写内存一样对文件进行操作。
函数:
[code=cpp;toolbar:false"> #include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
void *mmap64(void *addr, size_t length, int prot, int flags,int fd, off64_t offset);
int munmap(void *addr, size_t length);
相关文章推荐
- 进程通信----共享内存以及mmap函数实现共享内存
- linux多线程【8】mmap实现父子进程的共享内存通信,用信号量同步
- 进程通信-共享内存-mmap()-code3
- 进程通信-共享内存-mmap()-code1
- 进程的内存分配函数之brk和mmap(不考虑共享内存)的应用
- 共享内存:mmap函数实现
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---文件映射mmap方式
- Linux进程通信---共享内存 代码实现
- 进程通信(IPC)——实现共享内存
- Linux进程共享通信 -- mmap实现
- 11.python并发入门(part10 多进程之间实现通信,以及进程之间的数据共享)
- 进程通信之内存地址映射与共享,同时如何在Linux0.11下实现共享内存
- 进程通信-共享内存-mmap()
- 共享内存多进程间通信,进程间同步使用信号量来实现
- Linux下共享内存通信实现A进程死循环输出A后被C进程处理输出C
- linux下通过共享内存在进程之间实现通信(system V)
- 进程通信-共享内存-mmap()-code2
- php-通过共享内存实现消息队列和进程通信
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 进程通信方式--共享内存(shm)--实现自由通信