共享内存删除的安全“陷阱”
来源:互联网 发布:恢复qq聊天记录软件 编辑:程序博客网 时间:2024/05/15 03:52
共享内存就是使多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。其他进程能把同一段共享内存段“连接到”他们自己的地址空间里去。所有进程都能访问共享内存中的地址。如果一个进程向这段共享内存写了数据,所做的改动会即时被有访问同一段共享内存的其他进程看到。共享内存的使用大大降低了在大规模数据处理过程中内存的消耗,但是共享内存的使用中有很多的陷阱,一不注意就很容易导致程序崩溃。
比如,共享内存的删除中就存在陷阱。
1 共享内存脱离进程
当进程结束使用共享内存区时,要通过函数 shmdt 断开与共享内存区的连接,其原型如下
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
其中:
Shmaddr是共享内存的地址,是shmat的返回值。
另外,涉及到一个数据结构,
/* Obsolete, used only forbackwards compatibility and libc5 compiles */
struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_ipc_pid_t shm_cpid; /* pid of creator */
__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
unsigned short shm_nattch; /* no. of current attaches */
unsigned short shm_unused; /* compatibility */
void *shm_unused2; /* ditto - used by DIPC */
void *shm_unused3; /* unused */
};
进程脱离共享内存区后,数据结构 shmid_ds 中的 shm_nattch 就会减 1 。但是共享段内存依然存在,只有 shm_attch 为 0 后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除。一般来说,当一个进程终止时,它所附加的共享内存区都会自动脱离。
2 删除共享内存
当进程删除共享内存区时,要通过函数 shmdctl来删除已存在的共享内存,其原型如下
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, structshmid_ds *buf);
其中:
Shmid:是由shmget所返回的标记符。
Cmd:是要执行的动作。他可以有三个值,
IPC_STAT,设置shmid_ds结构中的数据反射与共享内存相关联的值。
IPC_SET,如果进程有相应的权限,将与共享内存相关联的值设置为shmid_ds数据结构中所提供的值。
IPC_RMID,删除共享内存段。
Buf:是一个指向包含共享内存模式与权限的结构的指针,删除的时候可以默认为0。
如果共享内存已经与所有访问它的进程断开了连接,则调用IPC_RMID子命令后,系统将立即删除共享内存的标识符,并删除该共享内存区,以及所有相关的数据结构;
如果仍有别的进程与该共享内存保持连接,则调用IPC_RMID子命令后,该共享内存并不会被立即从系统中删除,而是被设置为IPC_PRIVATE状态,并被标记为"已被删除"(使用ipcs命令可以看到dest字段);直到已有连接全部断开,该共享内存才会最终从系统中消失。
另外:一旦通过shmctl对共享内存进行了删除操作,则该共享内存将不能再接受任何新的连接,即使它依然存在于系统中!所以,可以确知,在对共享内存删除之后不可能再有新的连接,则执行删除操作是安全的;否则,在删除操作之后如仍有新的连接发生,则这些连接都将可能失败!
- 共享内存删除的安全“陷阱”
- (转)Linux共享内存使用常见陷阱与分析(4)-共享内存删除的陷阱
- 共享内存的删除
- 共享内存陷阱和分析
- 删除空闲共享内存的脚本
- Linux共享内存的查看和删除
- Linux共享内存的查看和删除
- Linux共享内存的查看和删除
- 手动删除shmget创建的共享内存
- 共享内存批量删除
- unix/linux共享内存应用与陷阱
- unix/linux共享内存应用与陷阱
- unix/linux共享内存应用与陷阱
- unix/linux共享内存应用与陷阱
- unix/linux共享内存应用与陷阱
- (转)Linux共享内存使用常见陷阱与分析(1)-超过共享内存的大小限制
- redis的内存陷阱
- redis的内存陷阱
- TiXmlDocument 解析 C++ vc xml元素文本修改
- 禁用JavaScript控制台调试
- 物理引擎chipmunk
- Android开发者应该知道的Android体系架构和开发库
- 如何从零开始建立个人网站
- 共享内存删除的安全“陷阱”
- 查看AR的数据是否传送至总帐
- spring下的bean单例模式与设计模式(GOF)中的单例模式区别
- android源代码中repo升级后出现的问题
- [二分搜索]Closest Sums uva10487
- 限制输入文本框小于30
- Android自定义组件之自动换行View
- 数据导入导出的几个关键点
- Stack的三种含义