由于这样做的原因可能很难理解,我向您介绍我的情况: 我有一个仅编译为Windows的专有程序,但该程序具有开放的C插件API。但是,我想让我的代码的一部分运行在本地应用程序上(并使用Linux的其他库和优势),并以快速的方式进行IPC。
两台机器都会创建自己的套接字/共享内存区域(假设它们事先已经协商好了区域的大小)。同时,它们选择一个端口号,一台机器成为服务器,另一台机器成为客户端。连接被初始化。
最初,两台机器中所有的“共享”内存都包含未初始化的数据(另一台机器可能对于任何给定的共享内存块具有不同的值)。
在连接关闭之前,如果其中任何一台机器写入任何共享内存区域的地址,就会向另一台机器发送一个带有更改信息的消息。Linux内核的炫酷功能可以被利用,以使即使是原始指针也可以完美地使用(见下文)。然而,我不知道如何在Windows中通过专门的ReadNetworkShared()
和WriteNetworkShared()
类似的过程来实现。
实现可以提供某种形式的同步机制,以允许网络范围的信号量、互斥锁等。
Linux内核特定的问题: 大多数现代通用硬件架构和操作系统都提供了一种保护内存免受用户进程恶意/错误/意外使用的方法。每当您读取/写入未映射到进程虚拟地址空间中的内存时,CPU将通知操作系统内核发生了页面错误。随后,内核(如果是类Unix)将向有问题的进程发送一个分段违规信号,或者换句话说,您会收到SIGSEGV。
隐藏的神奇秘密是SIGSEGV可以被捕获并处理。因此,我们可以mmap()
一些内存(共享内存区域),使用mprotect()
标记为只读,然后,每当我们尝试写入共享内存区域中的地址时,进程将接收到SIGSEGV。信号处理程序随后对由内核传递的siginfo_t
执行检查,并推断出两种操作之一。
abort()
或其他方式。splice()
)。然后,将要写入的页面标记为读/写,并设置一个定时器,以便在超时时间内将页面再次标记为只读,并通过套接字发送旧副本和现在已写入页面之间的(可能压缩的)差异(SIMD 可能会对您有所帮助)。然后处理程序返回,允许写入(和可能的其他写入!)完成,直到定时器触发。无论何时机器通过套接字接收到压缩数据,它都会被简单地解压缩并写入其所属位置。
希望这可以帮到您!
编辑:我刚刚发现预编辑设计中的一个明显缺陷。如果(压缩的)页面已发送到另一台机器,则该另一台机器将无法区分已在页面中修改和未修改的数据。这涉及到一种竞争条件,其中接收机器可能会丢失尚未发送的信息。但是,一些更多的 Linux 内核特定的东西可以解决这个问题。
/dev/shm
中创建文件,并从Wine和本地Linux应用程序访问它们。请注意,这不是一定存在的,所以你应该有备用的IPC方法。
https://superuser.com/questions/45342/when-should-i-use-dev-shm-and-when-should-i-use-tmp
否则,您可以尝试构建一个winelib应用程序,该应用程序可以从Linux调用您的Windows代码: http://web.archive.org/web/20150225173552/http://wine-wiki.org/index.php/WineLib#Calling_a_Native_Windows_dll_from_Linux。我也不确定它是否有效。
shm_open
。 - Sergei Krivonos