- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在编写一个出于性能原因使用共享内存的程序(已评估套接字和管道作为替代方案,但它们的速度不足以完成我的任务,一般来说,任何涉及拷贝的 IPC 方法都太慢)。在共享内存区域中,我正在编写许多固定大小的结构。有一个程序负责将结构写入共享内存,许多客户端从中读取。但是,客户端需要写入每个结构的一个成员(一个引用计数,它们将自动更新)。所有其他成员都应该只读给客户。
因为客户端需要更改那个成员,所以他们不能将共享内存区域映射为只读。但他们也不应该对其他成员进行修补,并且由于这些程序是用 C++ 编写的,因此内存损坏是可能的。理想情况下,一个客户端崩溃另一个客户端应该尽可能困难。我只担心有漏洞的客户端,而不是恶意客户端,因此允许不完美的解决方案。
我可以尝试通过在 header 中将它们使用的成员声明为 const 来阻止客户端覆盖,但这不能防止内存损坏(缓冲区溢出、错误转换等)覆盖。我可以插入 canaries ,但我必须不断支付检查它们的费用。
我可以将指向实际数据的指针存储在单独的映射只写页中,同时将结构保留在只读映射页中,而不是直接存储引用计数成员。这会起作用,如果我尝试写入指向的数据,操作系统将强制我的应用程序崩溃,但在尝试写入时可能不需要间接存储 lock free algorithms ,因为需要遵循另一个间接级别可以改变某事是否可以原子地完成。
有没有什么方法可以标记较小的内存区域,这样写入它们会导致您的应用程序崩溃?有些平台有硬件观察点,也许我可以通过内联汇编激活其中一个,但在 32 位 x86 上一次只能激活 4 个,每个只能覆盖结构的一部分,因为它们是有限的到 4 个字节。这也会让我的程序难以调试 ;)
编辑:我找到了 this rather eye popping paper ,但不幸的是,它需要使用 ECC 内存和修改后的 Linux 内核。
最佳答案
我不认为在操作系统级别让一些位只读是不可能的。
我刚才想到的一件事是您可以像您建议的那样将引用计数放在不同的页面中。如果结构的大小相同,并且都位于连续的内存位置,则可以使用指针算法从结构指针中定位引用计数,而不是在结构中使用指针。这可能比为您的用例提供指针更好。
long *refCountersBase;//The start address of the ref counters page
MyStruct *structsBase;//The start address of your structures page
//get address to reference counter
long *getRefCounter(MyStruct *myStruct )
{
size_t n = myStruct - structsBase;
long *ref = refCountersBase + n;
return ref;
}
关于c++ - 如果对给定内存位置的写入发生在比页面粒度更细的位置,你能强制崩溃吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2484959/
在命令提示符下,当你按下插入按钮时,光标从细条变为粗条,表明它处于覆盖模式,当你再次按下它时,它又变细表明它处于插入模式有什么办法可以在 C# 中执行此操作吗? 编辑:我想知道是否有办法使光标变粗/变
RubyRogues 播客上有人曾经说过“学习 CoffeeScript,因为 CoffeeScript 编写的 javascript 比你更好。”抱歉,不记得是谁说的... 所以,我采用了一个非常简
我是一名优秀的程序员,十分优秀!