设置为开发人员模式时,Cygwin不再支持Flask应用

尝试在后台使用以下命令运行我的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

该错误似乎源于在开发人员模式下运行,因为当我使用app.run_server(debug = False)运行时(顺便说一句,在我的本地环境中util.DEBUG设置为True),该应用程序运行良好,但随后我没有进行热装,这对我很重要.

我已尝试根据此帖子https://superuser.com/a/194537/276726重新设置cygwin,但这并不能解决任何问题.

我也尝试按照this post中的步骤创建一个特殊的变基文件,但这也无济于事.

该应用程序可从Windows命令行以开发模式运行,因此这是我目前的临时修复程序,但我希望我的Cygwin设置能够再次正常运行.

谢谢您的帮助!

最佳答案
在Cygwin世界中,您遇到了一个非常普遍的问题.有很多提到(处理)URL的URL,但是我将列出遇到的URL:

> [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 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 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 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 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,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(),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(). Sometimes Windows sets up a process environment that is even more hostile to fork() 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() failures to reappear.

See the 07009 section of the User’s Guide for the technical reasons it is so difficult to make fork() 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__);
}

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()

笔记:

>情况有所不同,我有一个常规的(虚拟).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):

Img0

定期重新设置基准(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窗口(检查其“首选基础”,并将其与上一张图像进行比较):

Img1

以及重新设置数据库的“查询”(现在从Mintty返回):

06007

更重要的是,运行代码:

06008

如图所示,它能够多次分叉(它只是因为按Enter才停止).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Python中的函数(二) 在上一篇文章中提到了Python中函数的定义和使用,在这篇文章里我们来讨论下关于函数的一些更深的话题。在学习C语言函数的时候,遇到的问题主要有形参实参的区别、参数的传递和改变、变量的作用域。同样在Python中,关于对函数的理解和使用也存在这些问题。下面来逐一讲解。一.函
Python中的字符串 可能大多数人在学习C语言的时候,最先接触的数据类型就是字符串,因为大多教程都是以&quot;Hello world&quot;这个程序作为入门程序,这个程序中要打印的&quot;Hello world&quot;就是字符串。如果你做过自然语言处理方面的研究,并且用Python
Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程。下面就来了解一下如何在Python中进行对象编程。一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。 类是对现实世界中一些事物的封装,
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定义和使用方法,这只体现了面向对象编程的三大特点之一:封装。下面就来了解一下另外两大特征:继承和多态。 在Python中,如果需要的话,可以让一个类去继承一个类,被继承的类称为父类或者超类、也可以称作基类,继承的类称为子类。并且Pytho
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非常熟悉,无论在哪门编程语言当中,函数(当然在某些语言里称作方法,意义是相同的)都扮演着至关重要的角色。今天就来了解一下Python中的函数用法。一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明
在windows下如何快速搭建web.py开发框架 用Python进行web开发的话有很多框架供选择,比如最出名的Django,tornado等,除了这些框架之外,有一个轻量级的框架使用起来也是非常方便和顺手,就是web.py。它由一名黑客所创建,但是不幸的是这位创建者于2013年自杀了。据说现在由
将Sublime Text 2搭建成一个好用的IDE 说起编辑器,可能大部分人要推荐的是Vim和Emacs,本人用过Vim,功能确实强大,但是不是很习惯,之前一直有朋友推荐SUblime Text 2这款编辑器,然后这段时间就试了一下,就深深地喜欢上这款编辑器了...
Python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句&quot;#include&lt;math.h&gt;&quot;引入math.h这个头文件,否则是无法正常进行调用的。那么在Python中,如果要引用一些内置的函数,该怎么处理呢?在Python中
Python的基础语法 在对Python有了基础的认识之后,下面来了解一下Python的基础语法,看看它和C语言、java之间的基础语法差异。一.变量、表达式和语句 Python中的语句也称作命令,比如print &quot;hello python&quot;这就是一条语句。 表达式,顾名思义,是
Eclipse+PyDevʽjango+Mysql搭建Python web开发环境 Python的web框架有很多,目前主流的有Django、Tornado、Web.py等,最流行的要属Django了,也是被大家最看好的框架之一。下面就来讲讲如何搭建Django的开发环境。一.准备工作 需要下载的
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便。 Ulipad下载地址: https://github.com/limodou/ulipad http://files.cnblogs.com/dolphin0520/u...
Python中的函数(三) 在前面两篇文章中已经探讨了函数的一些相关用法,下面一起来了解一下函数参数类型的问题。在C语言中,调用函数时必须依照函数定义时的参数个数以及类型来传递参数,否则将会发生错误,这个是严格进行规定的。然而在Python中函数参数定义和传递的方式相比而言就灵活多了。一.函数参数的
在Notepad++中搭配Python开发环境 Python在最近几年一度成为最流行的语言之一,不仅仅是因为它简洁明了,更在于它的功能之强大。它不仅能够完成一般脚本语言所能做的事情,还能很方便快捷地进行大规模的项目开发。在学习Python之前我们来看一下Python的历史由来,&quot;Pytho
Python中的条件选择和循环语句 同C语言、Java一样,Python中也存在条件选择和循环语句,其风格和C语言、java的很类似,但是在写法和用法上还是有一些区别。今天就让我们一起来了解一下。一.条件选择语句 Python中条件选择语句的关键字为:if 、elif 、else这三个。其基本形式如
关于raw_input( )和sys.stdin.readline( )的区别 之前一直认为用raw_input( )和sys.stdin.readline( )来获取输入的效果完全相同,但是最近在写程序时有类似这样一段代码:import sysline = sys.stdin.readline()
初识Python 跟学习所有的编程语言一样,首先得了解这门语言的编程风格和最基础的语法。下面就让我们一起来了解一下Python的编程风格。1.逻辑行与物理行 在Python中有逻辑行和物理行这个概念,物理行是指在编辑器中实际看到的一行,逻辑行是指一条Python语句。在Python中提倡一个物理行只
当我们的代码是有访问网络相关的操作时,比如http请求或者访问远程数据库,经常可能会发生一些错误,有些错误可能重新去发送请求就会成功,本文分析常见可能需要重试的场景,并最后给出python代码实现。
1.经典迭代器 2.将Sentence中的__iter__改成生成器函数 改成生成器后用法不变,但更加简洁。 3.惰性实现 当列表比较大,占内存较大时,我们可以采用惰性实现,每次只读取一个元素到内存。 或者使用更简洁的生成器表达式 4.yield from itertools模块含有大量生成器函数可
本文介绍简单介绍socket的常用函数,并以python-kafka中的源码socketpair为例,来讲解python socket的运用
python实践中经常出现编码相关的异常,大多网上找资料而没有理解原理,导致一次次重复错误。本文对常用Unicode、UTF-8、GB2312编码的原理进行介绍,接着介绍了python字符类型unicode和str以及常见编解码错误UnicodeEncodeError和UnicodeDEcodeEr