【问题标题】:Unix - Shared MemoryUnix - 共享内存
【发布时间】:2018-04-20 21:13:45
【问题描述】:

我正在使用共享内存,我的程序需要几个指针,但我有一个限制,只能使用一个标识符:

int idSh;
int * mem;
char * mem2;

idSh = Shmget (IPC_PRIVATE, sizeof (char *) + sizeof (int *), IPC_CREAT | 0700);
mem = Shmat (idSh,0,0);
mem2 = Shmat (idSh,0,0);

我必须在 Shmat 中使用多个指针,但我只有一段共享内存,标识符为 idSh。

有什么解决办法吗?

【问题讨论】:

  • 您是否尝试在进程之间共享指针?我认为这不会有用,您不能保证地址值在另一个进程中有效。见stackoverflow.com/questions/10776762/…
  • 是的,我正在尝试在进程之间共享指针,标识符是全局的。
  • 全局标识符对于进程来说仍然是唯一的,指向它们的指针对于进程也是唯一的。您不应将指针存储在共享区域中。如果它看起来有效,那么这是一个不能保证的巧合。
  • 如果你想共享数组,那么你应该在共享段内为这些数组分配内存并将内容复制到它们——你显然需要使用信号量之类的东西来同步它。
  • 来自shmat 的 Linux 手册页:使用 shmat() 和 shmaddr 等于 NULL 是附加共享内存段的首选、可移植方式。请注意,以这种方式附加的共享内存段可能会附加到不同进程中的不同地址。因此,在共享内存中维护的任何指针都必须是相对的(通常是相对于段的起始地址),而不是绝对的。

标签: c unix shared-memory


【解决方案1】:

您需要将“基于指针”的数据结构重写为“基于偏移量”,并在共享内存对象的开头创建一种目录。目录应该标识根数据结构的偏移量,因此每个访问器都可以适应它映射到的任何地址。坏消息是,这是一项繁琐的工作。好消息是它通常会使源库更好。 Offset based 具有各种优势,例如能够拍摄整个数据结构的快照,并编写可以离线分析它的实用程序。

基于偏移:如果您在链表中有一个节点,例如:

struct Node {
     MyType Data;
     struct Node *Link;
}

您需要将其更改为:

struct Node {
     MyType Data;
     uintptr_t Link;
}

然后遍历你的数据结构看起来像:

extern uintptr_t ShmemBase;
struct Node *Next = (struct Node *)(ShmemBase + Cur->Link);

虽然我敢打赌你可以更好地封装它,甚至可以将“链接”字段与特定的共享内存对象相关联。

我过去做过这些转换,它们通常没有你想象的那么糟糕。您确实对正确隐藏数据结构访问方法的人表示赞赏....

另外,系统通常可以被强制为所有参与者映射到一个统一地址的对象;因此,如果您对目标系统稍作修改,您可能会找到这些神奇的地址。如果你走这条路,最终会有人讨厌你。

【讨论】:

    猜你喜欢
    • 2012-04-15
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2015-07-20
    • 2012-03-20
    • 1970-01-01
    相关资源
    最近更新 更多