使用共享内存以及如何正确取消分配 space 和 IPC_RMID
Using shared memory and how to correctly unallocate a space with IPC_RMID
我的 linux 盒子上有 2 个应用程序 运行,一个服务器和一个客户端。我正在使用的服务器和客户端示例来自
Dave Marshalls examples.
一切正常,但是当我在我的后台进程中尝试这个并且我想扩展我的原始段时(可能由于将来的应用程序升级)我要么必须更改我的密钥要么以某种方式通过 shmctl(shmid, IPC_RMID, 0)
调用我的应用程序。由于我的应用程序无法优雅地退出,并且我无法在分配后一开始就设置它(因为一旦它被标记为删除,其他应用程序将无法使用此共享内存 space)我无法清理它space up.
到目前为止我想出的最好的方法是 shmget
我的旧部分,检查它是否存在,如果存在则清除它然后将它分配给一个高值。这看起来像:
void init_shared_mem(void)
{
int shmid;
key_t key = 0x1235; //key to be passed to shmget()
int oldSize = 27;
int newSize = 28;
char * shm;
//check to see if an allocation exists
if ((shmid = shmget(key, oldSize, IPC_CREAT | 0666)) < 0)
{
perror("shmget: shmget failed");
}
//unallocate it if it does
else if (shmctl(shmid , IPC_RMID , 0) == -1)
{
perror("shmid");
}
//reallocate new section
if ((shmid = shmget(key, newSize, IPC_CREAT | 0666)) < 0)
{
perror("shmget: shmget failed");
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
{
perror("shmat");
exit(1);
}
}
其他 SO 问题似乎没有涉及此问题或将其作为可能的问题提出。有没有更好的方法来做到这一点,我错过了,或者我可以简单地将它重新分配到更高的值而不是清除它?
您没有说明您 运行 使用的是哪个操作系统。如果你在 Linux, OpenBSD 5.1 or later or other operating systems configured a particular way you may well be able to attach after having done IPC_RMID
so long as something is still attached to it but bear in mind this behaviour is not portable (here's an older examination of IPC_RMID behaviour on different OSes)。没有这种行为,如果您的程序崩溃(又名 "doesn't exit graciously"),当它是附加到该段的最后一个东西时,将很难避免遗留陈旧的段。
我还应该注意到,您的问题听起来与 UNIX 套接字常见问题解答论坛 Options for robust process cleanup 中讨论的问题相似,其中的建议包括:使用 Linux 的 IPC_RMID
行为, 让监控父进程检查进程是否死亡并进行清理。
我的 linux 盒子上有 2 个应用程序 运行,一个服务器和一个客户端。我正在使用的服务器和客户端示例来自 Dave Marshalls examples.
一切正常,但是当我在我的后台进程中尝试这个并且我想扩展我的原始段时(可能由于将来的应用程序升级)我要么必须更改我的密钥要么以某种方式通过 shmctl(shmid, IPC_RMID, 0)
调用我的应用程序。由于我的应用程序无法优雅地退出,并且我无法在分配后一开始就设置它(因为一旦它被标记为删除,其他应用程序将无法使用此共享内存 space)我无法清理它space up.
到目前为止我想出的最好的方法是 shmget
我的旧部分,检查它是否存在,如果存在则清除它然后将它分配给一个高值。这看起来像:
void init_shared_mem(void)
{
int shmid;
key_t key = 0x1235; //key to be passed to shmget()
int oldSize = 27;
int newSize = 28;
char * shm;
//check to see if an allocation exists
if ((shmid = shmget(key, oldSize, IPC_CREAT | 0666)) < 0)
{
perror("shmget: shmget failed");
}
//unallocate it if it does
else if (shmctl(shmid , IPC_RMID , 0) == -1)
{
perror("shmid");
}
//reallocate new section
if ((shmid = shmget(key, newSize, IPC_CREAT | 0666)) < 0)
{
perror("shmget: shmget failed");
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
{
perror("shmat");
exit(1);
}
}
其他 SO 问题似乎没有涉及此问题或将其作为可能的问题提出。有没有更好的方法来做到这一点,我错过了,或者我可以简单地将它重新分配到更高的值而不是清除它?
您没有说明您 运行 使用的是哪个操作系统。如果你在 Linux, OpenBSD 5.1 or later or other operating systems configured a particular way you may well be able to attach after having done IPC_RMID
so long as something is still attached to it but bear in mind this behaviour is not portable (here's an older examination of IPC_RMID behaviour on different OSes)。没有这种行为,如果您的程序崩溃(又名 "doesn't exit graciously"),当它是附加到该段的最后一个东西时,将很难避免遗留陈旧的段。
我还应该注意到,您的问题听起来与 UNIX 套接字常见问题解答论坛 Options for robust process cleanup 中讨论的问题相似,其中的建议包括:使用 Linux 的 IPC_RMID
行为, 让监控父进程检查进程是否死亡并进行清理。