尝试在后台使用以下命令运行我的python flask应用程序后,立即发生了此问题:
$python app.py&
这立即失败了.之后,以后我再也没有问题地尝试运行该应用程序,最终都会出现此错误:
$python app.py
Running on http://127.0.0.1:8050/
Debugger PIN: 962-843-370
* Serving Flask app "app" (lazy loading)
* Environment: development
* Debug mode: on
2 [main] python3.6m 37104 child_info_fork::abort: unable to remap _lbfgsb.cpython-36m-x86_64-cygwin.dll to same address as parent (0x48E0000) - try running rebaseall
Traceback (most recent call last):
File "app.py",line 644,in <module>
app.run_server(debug=util.DEBUG)
File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/dash/dash.py",line 1293,in run_server
**flask_run_options)
File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/flask/app.py",line 943,in run
run_simple(host,port,self,**options)
File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/serving.py",line 812,in run_simple
reloader_type)
File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/_reloader.py",line 275,in run_with_reloader
sys.exit(reloader.restart_with_reloader())
File "/cygdrive/c/Users/mkupfer/Desktop/my_documents/01_Visualizations/eurostat/venv/lib/python3.6/site-packages/werkzeug/_reloader.py",line 132,in restart_with_reloader
close_fds=False)
File "/usr/lib/python3.6/subprocess.py",line 267,in call
with Popen(*popenargs,**kwargs) as p:
File "/usr/lib/python3.6/subprocess.py",line 709,in __init__
restore_signals,start_new_session)
File "/usr/lib/python3.6/subprocess.py",line 1275,in _execute_child
restore_signals,start_new_session,preexec_fn)
BlockingIOError: [Errno 11] Resource temporarily unavailable
@H_502_11@
该错误似乎源于在开发人员模式下运行,因为当我使用app.run_server(debug = False)运行时(顺便说一句,在我的本地环境中util.DEBUG设置为True),该应用程序运行良好,但随后我没有进行热装,这对我很重要.
我已尝试根据此帖子https://superuser.com/a/194537/276726重新设置cygwin,但这并不能解决任何问题.
我也尝试按照this post中的步骤创建一个特殊的变基文件,但这也无济于事.
该应用程序可从Windows命令行以开发模式运行,因此这是我目前的临时修复程序,但我希望我的Cygwin设置能够再次正常运行.
谢谢您的帮助!
> [SO]: Cygwin error: “-bash: fork: retry: Resource temporarily unavailable”
> [SO]: Cygwin issue – unable to remap; same address as parent
> [SuperUser]: Cygwin fatal error unable to remap.. What does it mean?
> [WordPress]: Cygwin and Rails – unable to remap to same address as parent; died waiting for dll loading,errno 11
> [SO]: Cygwin error: “child_info_fork::abort: Loaded to different address:”
[Cygwin]: Problems with process creation中很好地解释了“幕后魔术”(重点是我的):
The semantics of
fork@H_502_11@ require that a forked child process have exactly the same address space layout as its parent. However,Windows provides no native support for cloning address space between processes and several features actively undermine a reliable
fork@H_502_11@ implementation. Three issues are especially prevalent:
- DLL base address collisions. Unlike *nix shared libraries,which use “position-independent code”,Windows shared libraries assume a fixed base address. Whenever the hard-wired address ranges of two DLLs collide (which occurs quite often),the Windows loader must “rebase” one of them to a different address. However,it may not resolve collisions consistently,and may rebase a different dll and/or move it to a different address every time. Cygwin can usually compensate for this effect when it involves libraries opened dynamically,but collisions among statically-linked dlls (dependencies known at compile time) are resolved before
cygwin1.dll@H_502_11@ initializes and cannot be fixed afterward. This problem can only be solved by removing the base address conflicts which cause the problem,usually using the
rebaseall@H_502_11@ tool
.- Address space layout randomization (ASLR). Starting with Vista,Windows implements ASLR,which means that thread stacks,heap,memory-mapped files,and statically-linked dlls are placed at different (random) locations in each process. This behavIoUr interferes with a proper
fork@H_502_11@,and if an unmovable object (process heap or system dll) ends up at the wrong location,Cygwin can do nothing to compensate (though it will retry a few times automatically).
尝试在[Cygwin.FAQ]: 4.45. How do I fix fork() failures?中进行故障排除(重点仍然存在).冒着散布答案的风险,我将其粘贴在这里:
Unfortunately,Windows does not use the fork/exec model of process creation found in UNIX-like OSes,so it is difficult for Cygwin to implement a reliable and correct
fork()@H_502_11@,which can lead to error messages such as:
- unable to remap somedll to same address as parent
- couldn’t allocate heap
- died waiting for dll loading
- child -1 – died waiting for longjmp before initialization
- STATUS_ACCESS_VIOLATION
- resource temporarily unavailable
Potential solutions for the above errors:
- Restart whatever process is trying (and failing) to use
fork()@H_502_11@. Sometimes Windows sets up a process environment that is even more hostile to
fork()@H_502_11@ than usual.
- Ensure that you have eliminated (not just disabled) all software on the 07007.
- Switch from 32-bit Cygwin to 64-bit Cygwin,if your OS and cpu support that. With the bigger address space fork() is less likely to fail.
Try setting the environment variable CYGWIN to “detect_bloda”,which enables some extra debugging,which may indicate what other software is causing the problem.
See 07008 for more information.
Force a full rebase: Run rebase-trigger fullrebase,exit all Cygwin programs and run Cygwin setup.
By default,Cygwin’s setup program automatically performs an incremental rebase of newly installed files. Forcing a full rebase causes the rebase map to be cleared before doing the rebase.
See /usr/share/doc/rebase/README and /usr/share/doc/Cygwin/_autorebase.README for more details.
Please note that installing new packages or updating existing ones undoes the effects of rebase and often causes
fork()@H_502_11@ failures to reappear.
See the 07009 section of the User’s Guide for the technical reasons it is so difficult to make
fork()@H_502_11@ work reliably.
为了重现该问题,我使用了:
> Cygwin 32:
>遇到问题的机会要高得多
>这不是我的主要Cygwin环境
> Python 3.6.4 VEnv
>位于/home/cfati/Work/Dev/VEnvs/py_032_03.06.04_test0
我尝试重现您的确切行为(使用_lbfgsb * .dll),但是pip -v install scipy无法构建它.由于[SciPy]: Installing SciPy on Windows描述了一个相当复杂的过程,并且我无法保证最后我能够重现该问题,因此我尝试使用numpy的.dll(numpy已成功安装为scipy依赖项),但我没有这样做.能够(作为副作用,import numpy加载了一堆.dll),但是(通过subprocess.Popen)调用fork并没有失败.然后,我决定亲自处理这个问题,并创建一个加载一些.dll的小程序,然后分叉自身(同样,通过subprocess.Popen),以使问题尽可能重现.
dll.c:
#include <stdio.h>
#if defined(_WIN32)
# define DLL_EXPORT __declspec(dllexport)
#else
# define DLL_EXPORT
#endif
DLL_EXPORT int test() {
printf("[%s] (%d) - [%s]\n",__FILE__,__LINE__,__FUNCTION__);
}
@H_502_11@
code.py:
#!/usr/bin/env python3
import sys
import os
import subprocess
import time
import select
import random
import ctypes
DLLS = [os.path.join(os.path.dirname(__file__),"dll{:d}.dll".format(item)) for item in range(2)]
def main():
random.seed(os.getpid())
random.shuffle(DLLS)
if len(sys.argv) == 1:
print("Python {:s} on {:s}\n".format(sys.version.replace("\n",""),sys.platform))
print("Process 0x{:08X}".format(os.getpid()))
for dll in DLLS:
ctypes.cdll.LoadLibrary(dll)
idx = 0
while sys.stdin not in select.select([sys.stdin],[],1)[0]:
p = subprocess.Popen([sys.executable] + sys.argv + [str(idx)])
#p.communicate()
time.sleep(1)
idx += 1
else:
sleep_time = 3
print("Process 0x{:08X} (inner) will end in {:d} seconds".format(os.getpid(),sleep_time))
time.sleep(sleep_time)
if __name__ == "__main__":
main()
@H_502_11@
笔记:
>情况有所不同,我有一个常规的(虚拟).dll,而不是Python扩展模块,我尝试通过[Python 3.Docs]: ctypes – A foreign function library for Python加载它.无论Python如何看待它(作为一个模块),这都没有区别.,或作为外部.dll),仍然必须将其加载到进程中(以相同的方式)
>场景是:
>我加载了2个这样的.dll(实际上是相同的.dll以不同的名称复制,因此它们都具有相同的首选基址),因此第一个.dll可能会加载到该地址,而下一个.dll将装在另一个
>然后我分叉该过程,并在子级中基于随机因素切换.dll加载顺序
>当第二个.dll将在首选库中加载时,将与父进程不一致,从而产生错误
>最初,所有内容都在我的cwd中,然后(为了更贴近您的问题),我用文件创建了一个Python包.请注意,我没有采取正确的方式(通过setup.py文件安装),而是手动复制了所有内容
06002
因此,该错误是非常可重现的.我还要在此添加.dll详细信息(Dependency Walker):
定期重新设置基准(rebaseall)为什么不能解决问题?
> Cygwin软件包具有一个安装后脚本,该脚本在其.dll上调用重新设置
>在标准库路径(/ lib,/usr/lib,…)中重新搜索.可以根据/usr/share/doc/Cygwin/_autorebase.README进行调整:
Packages can make the potential locations of such dynamic objects
known by dropping a file (named after the package) in
/var/lib/rebase/dynpath.d/. If any dynamic objects are installed by
users,these locations should be advertised in /var/lib/rebase/user.d/
(the file name should be identical to the user name if there are
multiple users on this system)
由于包可能包含.dll,因此Python需要进行此类调整.
>点子一样的软件包没有安装后脚本(该脚本会重新设置其.dll)
> VEnv位于用户的主路径中,而不位于标准库路径中(因此,即使是rebaseall也会忽略它们)
请注意,所有重新基于基础的.dll文件都存储在DB:/etc/rebase.db(.${ARCH})中.
06003
为了使.dll被变基工具拾取,需要对它们进行公告.这可以通过两种方式完成:
>在其中一个自定义位置中指定它们,因此在下一次完全重新配置时,它们将不再被忽略(只需添加VEnv目录以及其他(如果有的话)):
06004
>手动重新建立.dll的基准
他们两个都为我工作,但是我将仅以第二变体为例(因为它更简单).该过程包括2个步骤:
>创建所有需要重新建立基础的.dll的列表
06005
>执行基准
>必须关闭所有Cygwin进程(包括服务:例如sshd)
>我从dash.exe(从Win,从Cygwin bin dir直接启动)启动命令,而不是从Mintty(注意提示)启动命令
06006
更新后的Dependency Walker窗口(检查其“首选基础”,并将其与上一张图像进行比较):
06007
更重要的是,运行代码:
06008
如图所示,它能够多次分叉(它只是因为按Enter才停止).