是否可以在不使用偏移量的情况下将指针存储在共享内存中? [英] Is it possible to store pointers in shared memory without using offsets?

查看:268
本文介绍了是否可以在不使用偏移量的情况下将指针存储在共享内存中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用共享内存时,每个进程都可以将共享区域映射到其各自地址空间的不同区域中.这意味着在共享区域中存储指针时,您需要将它们存储为共享区域开始的偏移量.不幸的是,这会使原子指令的使用复杂化(例如,如果您试图编写无锁算法).例如,假设您在共享内存中有一堆引用计数节点,这些节点是由单个编写者创建的.编写器会定期自动更新指针"p",以指向具有正参考计数的有效节点.读者希望以原子方式写入"p",因为它指向第一个元素是引用计数的节点(结构)的开头.由于p始​​终指向有效节点,因此增加引用计数是安全的,并且可以安全地取消引用'p'并访问其他成员.但是,这仅在所有内容都在同一地址空间中时才起作用.如果节点和"p"指针存储在共享内存中,则客户端将出现竞争状态:

When using shared memory, each process may mmap the shared region into a different area of its respective address space. This means that when storing pointers within the shared region, you need to store them as offsets of the start of the shared region. Unfortunately, this complicates use of atomic instructions (e.g. if you're trying to write a lock free algorithm). For example, say you have a bunch of reference counted nodes in shared memory, created by a single writer. The writer periodically atomically updates a pointer 'p' to point to a valid node with positive reference count. Readers want to atomically write to 'p' because it points to the beginning of a node (a struct) whose first element is a reference count. Since p always points to a valid node, incrementing the ref count is safe, and makes it safe to dereference 'p' and access other members. However, this all only works when everything is in the same address space. If the nodes and the 'p' pointer are stored in shared memory, then clients suffer a race condition:

  1. x =读取p
  2. y = x +偏移量
  3. 增加y的引用计数

在步骤2中,p可能会更改,x可能不再指向有效节点.我能想到的唯一解决方法是以某种方式强制所有进程就映射共享内存的位置达成一致,以便可以在mmap'd区域中存储实际指针而不是偏移量.有什么办法吗?我在mmap文档中看到MAP_FIXED,但是我不知道如何选择一个安全的地址.

During step 2, p may change and x may no longer point to a valid node. The only workaround I can think of is somehow forcing all processes to agree on where to map the shared memory, so that real pointers rather than offsets can be stored in the mmap'd region. Is there any way to do that? I see MAP_FIXED in the mmap documentation, but I don't know how I could pick an address that would be safe.

在x86上使用内联汇编和'lock'前缀,也许有可能构建增量ptr X,其偏移量Y等于Z"?其他架构上的等效选项?尚未编写大量汇编文件,也不知道所需的指令是否存在.

Using inline assembly and the 'lock' prefix on x86 maybe it's possible to build a "increment ptr X with offset Y by value Z"? Equivalent options on other architectures? Haven't written a lot of assembly, don't know if the needed instructions exist.

推荐答案

在较低级别,x86原子指令可以一次完成所有这些树步骤:

On low level the x86 atomic inctruction can do all this tree steps at once:

  1. x =读p
  2. y = x +偏移量增量
  3. 引用y

//
      mov  edi, Destination
      mov  edx, DataOffset
      mov  ecx, NewData
 @Repeat:
      mov  eax, [edi + edx]    //load OldData
//Here you can also increment eax and save to [edi + edx]          
      lock cmpxchg dword ptr [edi + edx], ecx
      jnz  @Repeat
//

这篇关于是否可以在不使用偏移量的情况下将指针存储在共享内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆