考虑使用get_user_pages(或get_page)映射来自调用进程的页面的 Linux 驱动程序。然后将页面的物理地址传递给硬件设备。进程和设备都可以读取和写入页面,直到双方决定结束通信。特别地,在调用get_user_pages返回的系统调用之后,通信可以继续使用页面。系统调用实际上是在进程和硬件设备之间建立一个共享内存区域。
我担心如果进程调用会发生什么fork(它可能来自另一个线程,并且可能在调用的系统调用get_user_pages正在进行中或稍后发生)。特别是,如果父级在fork后写入共享内存区域,我对底层物理地址了解多少(可能是因为copy-on-write而改变)?我想明白:
进程需要遵守哪些限制,以便我们的驱动程序的功能正常工作(即物理内存保持映射到父进程中的相同地址)。
exec几乎立即调用)来工作的常见情况。madvisewith MADV_DONTFORK,并且可以让内存从子进程的空间中消失,但它不适用于堆栈分配的缓冲区。我愿意被指出文档或源代码。我特别查看了Linux Device Drivers,但没有发现这个问题得到解决。即使只是应用于内核源代码的相关部分的 RTFS 也有点让人不知所措。
内核版本不是完全固定的,而是最近的版本(比如 ??2.6.26)。如果重要的话,我们只针对 Arm 平台(目前是单处理器,但多核即将到来)。
我需要我的服务来更新共享内存中的字段,以便客户端应用程序读取和显示.由于Session 0 Isolation,我发现我当前的解决方案无效.
我已经mutex在全局命名空间中重命名es来修复该元素,但它看起来并不像dll会在会话之间共享,尽管Session 0 Isolation的一个解决方案是:
"明确地为任何命名对象选择Local \或Global \命名空间,例如服务提供的事件或映射内存."
我不知道dll的哪个部分可以归类为命名对象,并且需要花费很长时间才能继续重新安装并逐步检查它.
我看到了命名频道的代码卷,并被推迟了.我不想创建一个触及磁盘的文件,因为我想象的是memoryMappedFile解决方案.dll的共享部分可以工作吗?否则最简单的是什么?
public ref class ServerGUIBridge
{
public:
#pragma data_seg(".sdata")
static int commonIntShouldBeGlobal = 0;
static bool hasBeenInitializedMakeMeGlobal = false;
#pragma data_seg()
#pragma comment(linker, "/section:.sdata,rws")
Run Code Online (Sandbox Code Playgroud)
我正在使用.NET 2.0,所以请不要使用WCF.
我有一个简单的要求可能很难解决.我确实找到了一些像这样或者这样的引线,但我似乎无法自述使用它们.前者甚至没有为我翻译成可构建的代码.我对Boost没有经验只是自己写这个,但在我看来这可能是一个常见的要求.
我也遇到过Interprocess STL Map,但我还没有把它组装成工作代码.
我想boost::interprocess是去的地方,除非我想从头开始创建一些共享内存映射.
我不关心便携性.我需要一个适用于MS编译器的解决方案,特别是VS 2010附带的解决方案.
这张海报似乎想要或多或少地想要做什么,除了我需要将GUID映射到任意长度的二进制缓冲区(但是int到字符串同样好作为起点).不幸的是,即使从实验开始,我也无法干净地编译代码.
此外,我有两个问题:A)是否可以自动(或至少可预测)增加/缩小共享内存以满足分配需求; B)假设一个进程创建映射,另一个进程如何"附加"它?
我不介意解决方案是否需要多个共享"段"以满足分配需求.它不一定必须是单个单片共享内存块.
任何帮助都非常感谢.
假设我有课Base和Derived : public Base.我使用boost :: interprocess库构建了一个共享内存段.是否可以使用与此类似的代码:
Base* b = new Derived();
write(b); //one app writes
Base* b2 = read(b); //second app reads
//b equals b2 (bitwise, not the ptr location)
Run Code Online (Sandbox Code Playgroud)
我在这里看到的问题是,例如,派生的Base类所需的空间是未知的(因此要分配多少shmem?)
问:如何通过应用程序之间的指针传递对象?
我在使用boost中的共享内存对象,因为需要将内存页锁定到物理内存中的实时C++应用程序.在增强中我没有看到这样做的方法.我觉得我错过了一些东西,因为我知道Windows和Linux都有办法做到这一点(mlock()和VirtualLock()).
我的问题是关于初始化使用shm_open()和获得的内存mmap()。我在几个地方看到的一个常见建议是shm_open()使用标志调用O_CREAT|O_EXCL:如果成功,则我们是共享内存的第一个用户并可以对其进行初始化,否则我们不是第一个用户,并且共享内存已被另一个进程初始化。
但是,根据我的了解shm_open以及在Linux上进行的测试,这是行不通的:即使在共享内存对象的最后一个用户未映射并关闭后,共享内存对象仍留在系统中。一个简单的测试程序,它要求shm_open有O_CREAT|O_EXCL,然后关闭描述符和退出,将在第一次运行成功,但仍然会失败的第二次运行,即使没有其他人使用当时的共享内存。
在我看来,实际上(至少在我测试的系统上)的行为与以下行为shm_open几乎完全相同open():如果我修改我的简单测试程序以将某些内容写入共享内存(通过通过获取的指针mmap)并退出,则共享内存对象将永久保留其内容(我可以运行另一个简单程序以读取我先前编写的数据)。
那么,如何使用的意见shm_open与O_CREAT|O_EXCL刚才错了,还是我失去了一些东西?
我确实知道可以使用删除共享内存对象shm_unlink(),但似乎只会引起更多问题:
如果进程在调用之前死亡,shm_unlink()那么我们将回到上述问题。
如果一个进程调用shm_unlink()而其他进程仍映射到同一共享内存中,则这些其他进程仍将照常继续使用它。现在,如果另一个进程来shm_open()使用相同的名称并O_CREAT指定了名称,则它实际上将成功创建具有相同名称的新共享内存对象,这与其他进程仍在使用的旧共享内存对象完全无关。现在,我们有一个进程试图通过共享内存与其他进程进行通信,而完全不知道它使用了错误的通道。
我习惯了Windows语义,即只有打开了至少一个句柄,共享内存对象才会存在,因此Posix的内容非常令人困惑。
我尝试学习如何在xcb库中使用共享内存pixmaps.您是否有过这方面的经验并希望分享示例代码和/或信息?这将非常有帮助.
谢谢
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <sys/shm.h>
int main() {
int i=0;
int shmid;
int *mem=(int*)malloc(10*sizeof(int));
key_t key;
key=1234;
pid_t pid;
shmid=shmget(1234,sizeof(*mem), IPC_CREAT|0666);
if(shmid==-1) {
printf("shmget error\n");
return -1;
}
mem=shmat(shmid, NULL, 0);
if(mem==(int*)-1) {
printf("shmat error\n");
return -1;
}
for(;i<10;i++) {
*(mem+i)=0;
}
pid=fork();
if(pid<0) {
fprintf(stderr,"Fork Failed");
printf("array : ");
}
else if (pid==0) {
printf("producer is created.\n");
printf("array : ");
for(i=0;i<10;i++) {
printf("%d ", *(mem+i));
}
printf("\n");
for(i=0;i<10;i++) {
*(mem+i)=i+1; …Run Code Online (Sandbox Code Playgroud) 在UNIX世界中,创建由RAM或页面文件而不是磁盘文件支持的文件映射对象的标准方法是调用shm_open。这将创建一个具有名称的内存映射,并返回可传递给的文件句柄mmap。
问题在于它创建了一个名称。如果我可以创建一个匿名内存映射,那就太好了。这将解决两个问题:
shm_unlink之后立即调用shm_open是一种可能,但是这会留下一个小窗口,在该窗口中突然终止会将该对象保留到下次重新启动为止。在Linux中,有memfd_create解决此问题的方法。同样,Windows允许传递一个空名称CreateFileMappingW来创建匿名映射。
Mac OS是否具有等效功能?
通过检查我的Windows机器中的几个DLL(例如KERNEL32.DLL),我注意到它们的所有部分,甚至是只读数据部分都没有设置IMAGE_SCN_MEM_SHARED标志.
DLL是从.dll文件映射的,所以只有当你读取文件的页面时才会将它复制到物理内存中,但是,如果同一个页面让进程A和进程B都访问了kernel32.dll,那么页面将会在物理内存中存在两次.我要求最后一句话的真实性.
如果.text或.rodata段共享它们将被仅复制到物理内存中,即使启用了ASLR,因为ASLR的作用是在模块首次加载时随机化模块的基础(应用相应的重定位)但是加载此模块的下一个进程直到系统重新启动将使模块处于相同的地址,因此.text和.rodata可以以相同的方式共享.
这些都是我做的假设,请指正.
谢谢!