如何在linux程序和windows程序之间通过Wine(同一台计算机)共享内存

How to share memory between linux program and windows program running through Wine (same computer)?

本文关键字:程序 内存 共享 一台 计算机 linux windows 之间 Wine      更新时间:2023-10-16

是否有一种方法(然后如何)在linux程序和通过wine运行的windows程序之间共享内存?

因为很难理解为什么要这样做,我给你我的情况:我有一个专门为windows编译的程序,但是这个程序有一个开放的C插件API。但是,我想让我的部分代码在本地应用程序上运行(并使用其他库和linux的其他优势),并以快速的方式进行IPC

Wine的目的是在Unix(类)系统上提供一个类似winapi的环境。这意味着Wine可以被看作是一个独立的、带有api的、"独立的"操作系统,它位于类unix系统之上。因此,您所说的机器实际上可能有两个操作系统,一个在另一个之上。首先是"真实的"(控制真实硬件),即GNU/Linux。其次,在POSIX/SUS接口之上有WinAPI实现,称为Wine。

而且,就人类而言,有一种,而且只有一种可移植的方法可以在具有不同操作系统的机器之间创建进程间通信,您可能已经注意到,我指的是套接字。

Wine子系统可以被认为是一个半虚拟机,它独立于Linux内核,但同时又与Linux内核紧密耦合。

为了提高效率,我的建议是使用套接字与我所说的SHMNP(共享内存网络协议)相结合来提供网络范围的共享内存。同样,请记住,两台"机器"(尽管物理上只有一台)应该被认为是独立的。Wine的实现太脏了,笨拙的细节无法轻易解决(尽管与Cygwin的hack相比,这没什么)。

SHMNP就是这样工作的。但是请注意,SHMNP 不存在 !这只是理论上的,协议结构没有给出明显的原因。

  • 两台机器都创建自己的套接字/共享内存区域(假设它们之前协商了该区域的大小)。同时,他们选择一个端口号,其中一台机器成为服务器,另一台成为客户端。初始化连接

  • 最初,两台机器中的所有"共享"内存都包含未初始化的数据(另一台机器可能对任何给定的共享内存块有不同的值)。

  • 在连接关闭之前,如果两台机器中的任何一台写入共享内存区域的任何一个地址,将向另一台机器发送一条消息,其中包含更改的信息。可以利用Linux内核的古怪特性,甚至允许原始指针完美地工作(见下文)。然而,我不知道在Windows中这样做,而是通过专门的ReadNetworkShared()WriteNetworkShared()类程序。

  • 实现可能会提供某种同步机制,以便允许网络范围的信号量,互斥体,

Linux kernel specific quirks:大多数现代通用硬件体系结构和操作系统都提供了一种保护内存免受用户进程恶意/错误/意外使用的方法。每当您读取/写入未映射到进程虚拟地址空间中的内存时,CPU将通知操作系统内核发生了页面错误。随后,内核(如果Unix(-like))将向违规进程发送一个分段冲突信号,或者换句话说,您接收到SIGSEGV。

隐藏的神奇秘密是SIGSEGV可以被捕获和处理。因此,我们可以mmap()一些内存(共享内存区域),用mprotect()将其标记为只读,然后,每当我们尝试写入共享内存区域中的地址时,进程将收到SIGSEGV。信号处理程序随后在内核传递的siginfo_t中执行检查,并推断出两个动作之一。

  • 如果故障地址不在共享内存区、abort()或其他地址
  • 否则,要写入的页面将被复制到临时存储(可能使用splice() ?)然后,将要写入的页面标记为读/写,并设置一个计时器,以便在超时时间内将页面再次标记为只读,并通过套接字发送旧副本和现在写入的页面之间的(可能被压缩的)差异(SIMD可以在这里提供帮助)。然后处理程序返回,允许写操作(可能还有其他写操作!)在没有进一步干预的情况下完成,直到计时器触发。

当一台机器通过套接字接收到压缩数据时,它只是被解压缩并写入它所属的位置。

希望这对你有帮助!

Edit:我刚刚发现了预编辑设计的一个明显缺陷。如果将(压缩的)页面发送到另一台机器,那么另一台机器将无法区分页面中已修改的数据和未修改的数据。这涉及到一个竞争条件,在这种情况下,接收机器可能会丢失它尚未发送的信息。然而,一些特定于linux内核的东西修复了它。

我不确定这是一个好主意,或者它是否会工作,但是你可以在/dev/shm中创建文件,并从Wine和你的本地Linux应用程序访问它们。

它不能保证存在,所以你应该有一个回退IPC方法。

https://superuser.com/questions/45342/when-should-i-use-dev-shm-and-when-should-i-use-tmp

否则,您可以尝试构建一个可以从Linux调用Windows代码的winelib应用程序:http://web.archive.org/web/20150225173552/http://wine-wiki.org/index.php/WineLib#Calling_a_Native_Windows_dll_from_Linux。我也不确定它是否会工作。