shmdt函数
功能:将共享内存段与当前进程脱离
原型:
- int shmdt(const void *shmaddr);
参数:
shmaddr: 由shmat所返回的指针
返回值:
成功返回0;失败返回-1
-
- int main()
- {
-
- int shmid = shmget(0x15764221, 1024 * sizeof(int), 0666 | IPC_CREAT);
- if (shmid == -1)
- {
- err_exit("shmget error");
- }
-
-
- int *pArray = static_cast<int *>(shmat(shmid, NULL, 0));
- if (pArray == (void *)-1)
- {
- err_exit("shmat error");
- }
-
- sleep(10);
-
-
- if (shmdt(pArray) == -1)
- {
- err_exit("shmdt error");
- }
- sleep(10);
-
- return 0;
- }
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数
功能:用于调控/获取共享内存属性
原型:
- int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(三个取值见下)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
![](https://img-blog.csdn.net/20141127154110562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvempmMjgwNDQxNTg5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
返回值:
成功返回0;失败返回-1
-
- int main()
- {
-
- int shmid = shmget(0x15764221, 1024 * sizeof(int), 0666 | IPC_CREAT);
- if (shmid == -1)
- {
- err_exit("shmget error");
- }
-
-
- int *pArray = static_cast<int *>(shmat(shmid, NULL, 0));
- if (pArray == (void *)-1)
- {
- err_exit("shmat error");
- }
-
- int choice = 0;
- cout << "Please input your choice: 0-detach, other-continue: ";
- cin >> choice;
- if (choice == 0)
- {
-
- if (shmdt(pArray) == -1)
- {
- err_exit("shmdt error");
- }
- }
-
-
- cout << "\nPlease input your choice: 0-delete, other-quit: ";
- cin >> choice;
- if (choice == 0)
- {
-
- if (shmctl(shmid,IPC_RMID,NULL) == -1)
- {
- err_exit("shmctl error");
- }
- else
- {
- cout << "Delete Success!" << endl;
- }
- }
-
- return 0;
- }
-
-
-
-
- int main()
- {
- const int NUMBER = 36;
- int shmid = shmget(0x15764221, NUMBER * sizeof(int), 0666 | IPC_CREAT);
- if (shmid == -1)
- {
- err_exit("shmget error");
- }
-
- int *pArray = static_cast<int *>(shmat(shmid, NULL, 0));
- if (pArray == (void *)-1)
- {
- err_exit("shmat error");
- }
-
- for (int i = 0; i < NUMBER; ++i)
- {
- *(pArray+i) = i+1;
- }
-
- int choice = 0;
- cout << "Please input your choice: 0-delete, other-quit: ";
- cin >> choice;
- if (choice == 0)
- {
-
- if (shmctl(shmid,IPC_RMID,NULL) == -1)
- {
- err_exit("shmctl error");
- }
- else
- {
- cout << "Delete Success!" << endl;
- }
- }
-
- return 0;
- }
-
- int main()
- {
- const int NUMBER = 36;
- int shmid = shmget(0x15764221, NUMBER * sizeof(int), 0666);
- if (shmid == -1)
- {
- err_exit("shmget error");
- }
-
- int *pArray = static_cast<int *>(shmat(shmid, NULL, 0));
- if (pArray == (void *)-1)
- {
- err_exit("shmat error");
- }
-
- int choice = 0;
- cout << "Please input your Choice: 0-read, other-quit: ";
- cin >> choice;
- if (!choice)
- {
- for (int i = 0; i < NUMBER; ++i)
- {
- cout << *(pArray+i) << "\t";
- }
- cout << endl;
- }
-
- return 0;
- }
![](https://img-blog.csdn.net/20141127154242219?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvempmMjgwNDQxNTg5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
由上图可知:即使其中一个进程执行了IPC_RMID(只要该共享内存引用计数不为0),该共享内核还是可读的(但此时必须该读进程是已经连接到该共享内存的,不然的话,写进程虽然没有将共享内存真正的删掉,但是其键值已经变为0x00000000(Private),此时其他进程是连接不上的)!
总结:
1.共享内存被别的程序占用,则删除该共享内存时,不会马上删除
2.此时会出现一个现象:该共享内存的key变为0x00000000,变为私有
3.此时还可以读,但必须还有办法获取该共享内存的ID(shmid),因为此时试图通过该共享内存的key获取该共享内存,都是白费的!