shmdt() 与 shmctl() 的区别
http://blog.sina.com.cn/s/blog_818dc7aa0100v3n3.html
操作共享內存,我們用到了下面的函數
==============================================
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmid = shmget( key_t shmkey , int shmsize , int flag );
(void *)shmaddr = shmat( int shmid , char *shmaddr , int shmflag );
int shmdt( char *shmaddr );
【shmget】—— 是用來開辟/指向一塊共享內存的函數
?參數:
???? shmkey??? 是這塊共享內存的標識符,如果是IPC_PRIVATE,則表示使用系統分配的鍵值創建;
???? shmsize?? 申請內存大小
???? flag????? 標志、權限;
?????????????? 當只有IPC_CREAT選項打開時,不管是否已存在該塊共享內存,則都返回該共享內存的ID,若不存在則創建共享內存;
?????????????? 當只有IPC_EXCL選項打開時,不管有沒有該塊共享內存,shmget()都返回-1;(即:單獨使用該標志無意義)
?????????????? 當IPC_CREAT | IPC_EXCL時, 如果沒有該塊共享內存,則創建,并返回共享內存ID,若已有該塊共享內存,則返回-1;
?返回值:
??????? shmid? 內存標識的ID
???????
【shmat】—— 鏈接上指定ID標識的共享內存
?參數:
???? shmid???? 內存標識ID,由shmget()函數返回;
???? shmaddr?? (輸出參數)共享內存的首地址,同該函數返回值一致;
???? shmflag?? SHM_RDONLY 只讀, 0 可讀寫;(SHM_COPY\SHM_MAP\SHM_RND不在此說明)
?
【shmdt】—— 斷開鏈接的共享內存指針
?參數:
???? shmaddr??? 調用函數shmat()鏈接上共享內存的指針;
?
當一個進程不再需要共享內存段時,它將調用shmdt()系統調用取消這個段,但是,這并不是從內核真正地刪除這個段,而是把相關shmid_ds結構的 shm_nattch域的值減1,當這個值為0時,內核才從物理上刪除這個共享段
========================================================
用來控制共享內存的shmctl()函數如下:
=========================================================
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl( int shmid , int cmd , struct shmid_ds *buf );
【shmctl】—— 控制共享內存
?參數:
???? shmid?? 共享內存標識ID;
???? cmd???? IPC_STAT 得到共享內存的狀態
???????????? IPC_SET 改變共享內存的狀態
???????????? IPC_RMID 刪除共享內存
???? buf???? 是一個結構體指針。IPC_STAT的時候,取得的狀態放在這個結構體中。如果要改變共享內存的狀態,用這個結構體指定;
struct shmid_ds結構體
?? struct shmid_ds {
?????? struct ipc_perm shm_perm;???????
?????? int???? shm_segsz;??????????????
?????? time_t? shm_atime;??????????????
?????? time_t? shm_dtime;??????????????
?????? time_t? shm_ctime;??????????????
?????? unsigned short? shm_cpid;???????
?????? unsigned short? shm_lpid;???????
????? ?short?? shm_nattch;?????????????
?????? unsigned short?? shm_npages;????
????? unsigned long?? *shm_pages;?????
??????????????? struct vm_area_struct *attaches;
?? };
?
IPC_RMID 命令實際上不從內核刪除一個段,而是僅僅把這個段標記為刪除,實際的刪除發生在最后一個進程離開這個共享段時。
==========================================================
總結:
shmdt(addr)使進程中的shmaddr指針無效化,不可以使用,但是保留空間。
shmctl(shmid,IPC_RMID,0) 刪除共享內存,徹底不可用,釋放空間。
轉載于:https://www.cnblogs.com/javaexam2/archive/2012/04/05/2632843.html
總結
以上是生活随笔為你收集整理的shmdt() 与 shmctl() 的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DevExpress 里实现单选按钮
- 下一篇: Ajax原理以及优缺点