我知道Cygwin,我知道它的缺点。我也知道fork
的缓慢,但不是为什么在地球上不可能解决这个问题。我也知道Cygwin需要一个DLL。我也理解POSIX定义了一个完整的环境(shell等等),这不是我真正关心的。
我的问题是询问是否有其他方法可以解决这个问题。我看到MinGW项目正在实现越来越多的POSIX功能,但是没有完整的解决方案提供完整的(与Linux / Mac / BSD实现状态相当)POSIX功能。
这个问题归结为: Win32 API(从MSVC20开始)可以有效地用于通过Windows API提供完整的POSIX层吗?
也许这将成为一个完整的libc,它只能访问OS库,用于文件系统访问,线程和进程控制等低级事务。但我不确切知道POSIX究竟包含了什么。我怀疑一个库可以将Win32变成符合POSIX标准的实体。
答案 0 :(得分:5)
POSIX<>的Win32。
如果您正在尝试编写以POSIX为目标的应用,为什么不使用* N * X的某些变体?如果您更喜欢运行Windows,则可以在PC /笔记本电脑等上运行Linux / BSD / Hyper-V / VMWare / Parallels / VirtualBox内的任何内容。
Windows曾经有一个与Win32子系统一起运行的POSIX兼容环境,但由于缺乏需求而在NT4之后停止运行。微软收购了Interix并发布了Services For Unix (SFU)。虽然它仍然是available for download,但SFU 3.5现已弃用,不再开发或支持。
至于为什么fork这么慢,你需要理解fork不仅仅是“创建一个新进程”,而是“创建一个新进程(本身是一个昂贵的操作),它与调用进程一起重复所有记忆“。
在* N * X中,分叉进程被映射到与父进程相同的内存页面(即非常快),并且只有在分叉进程尝试修改任何共享页面时才会给出新页面。这称为写入时的副本。这在很大程度上是可以实现的,因为在UNIX中,父进程和分叉进程之间没有硬性障碍。
另一方面,在NT中,所有进程都由CPU硬件强制执行的屏障隔开。在NT中,生成可以访问进程内存和资源的并行活动的最简单方法是创建一个线程。线程在创建过程的内存空间内运行,并且可以访问所有进程的内存和资源。
你可以通过各种形式的IPC,RPC,命名管道,邮件槽,memory-mapped files在进程之间共享数据,但每种技术都有自己的复杂性,性能特征等。阅读{ {3}}了解更多详情。
因为它试图模仿UNIX,所以CygWin的'fork'操作会创建一个新的子进程(在它自己的独立内存空间中),并且必须复制新分叉子进程内父进程中的每一页内存。这可能是一项非常昂贵的操作。
同样,如果你想编写POSIX代码,请在* N * X而不是NT中执行。
答案 1 :(得分:1)
这个怎么样
大多数Unix API都是由POSIX.DLL动态加载(共享)库实现的。与POSIX.DLL链接的程序在Win32子系统而不是POSIX子系统下运行,因此程序可以自由地混合Unix和Win32库调用。
来自http://en.wikipedia.org/wiki/UWIN
UWIN环境可能正是您所寻找的,但请注意它是在research.att.com上托管的,而UWIN是在自由许可下分发的,而不是GNU许可。此外,由于它是关于att的研究,并且只有2或者它们正在分发使用的东西,因此文档存在很多问题。
查看更多信息,请参阅我的文章,作为Regarding 'for' loop in KornShell
的最后答案主要的UWIN链接是该帖子中的错误链接,请尝试
http://www2.research.att.com/sw/download/
另外,你可以看一下
了解功能与问题。
我希望这会有所帮助。
答案 2 :(得分:1)
问题实际上归结为:Win32 API(从MSVC20开始??) 有效地用于在Windows上提供完整的POSIX层 API?
简短回答:否。
“完成POSIX ”意味着fork(),mmap(),signal()等等,这些[几乎]无法在NT上实现。
驱动点回家:GNU Hurd has problems with fork() as well,因为Hurd内核不是POSIX。
NT也不是POSIX。
另一个区别是持久性:
在符合POSIX标准的系统中,可以创建系统对象并将其保留在那里。此类对象的示例是命名管道和共享内存对象(shms)。您可以创建命名管道或shm,并将其保留在文件系统中(或在类似特殊文件系统的位置),其他进程将能够访问它。缺点是进程可能会死亡并且无法自行清理,留下未使用的对象(你知道僵尸进程吗?同样的事情)。
在NT中,每个对象都被引用计数,并在其最后一个句柄关闭时被销毁。文件是少数持续存在的对象之一。
符号链接是一个文件系统功能,并不完全依赖于NT内核,但是当前的实现(在Vista及更高版本中)无法创建与对象类型无关的符号链接。也就是说,符号链接是文件或目录,并且必须链接到文件或目录。如果目标的类型错误,则符号链接将不起作用。如果在创建符号链接时目标存在,则可以为其指定正确的类型,但POSIX要求可以在不存在目标的情况下创建符号链接。我无法想象一个首先指向文件,然后指向目录的符号链接的用例,但是POSIX说这应该有用,如果没有,你就不是完全符合POSIX的。或者,如果您的符号链接API /实用程序可以指定正确的类型,当目标不存在时,也会破坏POSIX兼容性。
可以在某种程度上复制某些POSIX功能(例如“整个描述符来自单个命名空间,引用任何I / O对象,并且选择()能够”而不会牺牲[性能,但这仍然是一项重大任务,POSIX接口确实是限制性的(也就是说,如果你可以再为该函数添加一个参数,那么就可以做正确的事......但你不能不,除非你想要抛弃POSIX合规性。)
您最好的选择是不要依赖难以移植到非POSIX系统的POSIX功能,或者以较低级别可能具有针对不同操作系统的单独实现的方式进行抽象,并且上级不关心的信息。