如何在通过Wine(同一台计算机)运行的linux程序和Windows程序之间共享内存? [英] How to share memory between linux program and windows program running through Wine (same computer)?

查看:69
本文介绍了如何在通过Wine(同一台计算机)运行的linux程序和Windows程序之间共享内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a way (and then how to) share memory between a linux program and a windows program running through wine ?

由于可能很难理解为什么要这样做,所以我给你我的处境: 我有一个仅针对Windows编译的专有程序,但是该程序具有开放的C插件API.但是,我想将我的代码的一部分运行在本机应用程序上(并使用其他库和linux的其他优点),并以快速的方式进行IPC

Since it could be hard to understand why to do such a thing, I give you my situation : I've a proprietary program compiled only for windows, but this program has an open C plugin API. But, I'd like to make part of my code running on a native application (and use other libraries and other advantages of linux), and doing the IPC in a fast way

推荐答案

Wine的目的是在Unix(类)系统上提供类似WinAPI的环境.这意味着Wine可以被视为独立的,基于API的,独立于顶部的Unix系统.因此,您说的那台机器实际上可能有两个操作系统,一个在另一个上.首先,真实"(控制真实硬件),即GNU/Linux.其次,在POSIX/SUS接口的顶部有一个称为Wine的WinAPI实现.

The purpose of Wine is to provide a WinAPI-like environment on Unix(-like) systems. This implies that Wine may be considered a separate, API-facaded, "independent" operating system on top and along a Unix-like system. Thus, that machine you say may actually have two OSes, one over the other. Firstly, the "real" (controlling real-hardware) one, that is, GNU/Linux. Secondly, there is the WinAPI implementation known as Wine in top of the POSIX/SUS interfaces.

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

And, as far as humankind is concerned, there's one, and only one single portable way to create inter-process communication between machines with different operating systems, and, as you may have already noticed, I refer to sockets.

Wine子系统本身可以被视为半虚拟机,与Linux内核隔离,但同时又紧密耦合.

The Wine subsystem may be considered a semi-virtual machine by its own right, isolated from the Linux kernel, but tightly coupled to it at the same time.

出于效率目的,我的建议是将哪些套接字与我所谓的SHMNP(共享内存网络协议)结合使用,以提供全网络共享内存.同样,请记住,两个机器"(尽管实际上只是一个)都应该是独立的. Wine实作太脏了,笨拙的细节无法轻易解决(尽管与Cygwin的骇客相比没什么).

For efficiency purposes, my proposal is to use what sockets in conjunction with what I call the SHMNP (Shared Memory Network Protocol) to provide network-wide shared memory. Again, remember, both "machines" (although it's physically just one) shall be though to be independent. The Wine implementation is too dirty for the clumsy details to be easily work-arounded (although that's nothing compared to Cygwin's hacks).

SHMNP以这种方式工作.但是请注意,SHMNP不存在 !这只是理论上的,出于明显的原因未给出协议结构 etal .

The SHMNP works this way. Note, however, that the SHMNP does not exist! It's just theoretical, and the protocol structures et al are not presented for obvious reasons.

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

  • Both machines create their own sockets/shared-memory areas (it's assumed they negotiated the area's size previously). At the same time, they choose a port number and one of the machines becomes the server, the other one becoming the client. The connection is initialized.

最初,两台计算机上的所有共享"内存都包含未初始化的数据(另一台计算机对于任何给定的共享内存块可能具有不同的值).

Initially, all "shared" memory in both machines contains uninitialized data (the other machine may have different values for any given shared memory block).

在关闭连接之前,如果两台计算机中的任何一台写入共享存储区的地址中的任何一个,均应将一条消息和已更改的信息发送到另一台计算机.可以利用Linux内核的时髦功能,甚至允许原始指针与此完美配合(见下文).但是,我不知道要在Windows中执行此操作,而是要通过专门的ReadNetworkShared()WriteNetworkShared()类过程来执行此操作.

Until the connection is closed, if any of the two machines write to any of address of the shared memory area, a message shall be sent to the other machine with the information that changed. The Linux kernel's funky features may be exploited to allow even raw pointers to work perfectly fine with this (see below). I'm, however, not aware of doing it in Windows rather that by specialized ReadNetworkShared() and WriteNetworkShared()-like procedures.

该实现可以提供某种同步机制,以便允许网络范围内的信号灯,互斥锁等.

The implementation may provide some sort of synchronization mechanism, so to allow network-wide semaphores, mutexes, et al.

Linux内核特定的怪癖: 大多数现代通用硬件体系结构和操作系统都提供了一种保护内存的方式,以防止用户进程恶意/无用/意外使用内存.每当您对未在进程的虚拟地址空间中映射的内存进行读/写操作时,CPU都会通知操作系统内核

Linux kernel specific quirks: Most modern general-purpose hardware architectures and operating systems provide for a way to protect memory from malicious/buggy/unintended use by a user process. Whenever you read/write to memory that isn't mapped in your process's virtual address space, the CPU will notify the operating system kernel that a page fault has occured. Subsequently, the kernel (if Unix(-like)) will send a segmentation violation signal to the offending process, or in other words, you receive SIGSEGV.

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

The hidden magical secret is that SIGSEGV may be caught, and handled. Thus, we may mmap() some memory (the shared memory area), mark it as read-only with mprotect(), then, whenever we try to write to an address in the shared memory area, the process will receive a SIGSEGV. The signal handler subsequently performs checks in the siginfo_t passed on by the kernel, and deduces one of two actions.

  • 如果错误地址是共享内存区域中的 not ,则为abort()或其他任何内容.
  • 否则,应将要写入的页面复制到一个临时存储中(也许借助splice()?).然后,将要写入的页面标记为读/写,并设置一个计时器,以便在超时内将该页面再次标记为只读,并发送旧副本和现在写入的页面之间的(可能是压缩的)差异通过插槽(SIMD可能会在这里为您提供帮助).然后,处理程序返回,从而允许写操作(可能还有其他写操作!)完成操作而无需进一步干预,直到计时器触发.
  • If the faulty address is not in the shared memory area, abort() or whatever.
  • Otherwise, the to be written page shall be copied to a temporary storage (maybe with the help of splice()?). Then, mark the to be written page as read/write, and setup a timer so that in within a timeout the page is marked read-only again and the (maybe compressed) difference between the old copy and the now-written page is sent through the socket (SIMD may help you here). The handler then returns, allowing the write (and maybe, other writes!) to complete without further intervention until the timer fires out.

每当机器通过套接字接收压缩数据时,只需对其进行解压缩并将其写入所在位置.

Whenever a machine receives compressed data through the socket, it's simply decompressed and written where it belongs.

希望这对您有所帮助!

编辑:我刚刚发现了预编辑设计的明显缺陷.如果将(压缩的)页面发送到另一台计算机,则该另一台计算机将无法区分页面内已修改的数据和未修改的数据.这涉及竞争状况,接收机器可能会丢失尚未发送的信息.但是,还有其他一些Linux内核特定的东西可以修复它.

Edit: I just found an obvious flaw of the pre-edit design. If a (compressed) page was sent to another machine, that other machine would be unable to differentiate between data that has been modified within the page and data that hasn't been modified. This involves a race condition, where the receiving machine may lose information it hasn't yet sended. However, some more Linux-kernel-specific stuff fixes it.

这篇关于如何在通过Wine(同一台计算机)运行的linux程序和Windows程序之间共享内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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