老实说,这个问题并不像它好奇的那样严重。 我发现导入NLTK时,它将导致任何Python子进程在网络调用中过早终止。 示例代码:
from multiprocessing import Process
import nltk
import time
def child_fn():
print "Fetch URL"
import urllib2
print urllib2.urlopen("https://www.google.com").read()[:100]
print "Done"
while True:
child_process = Process(target=child_fn)
child_process.start()
child_process.join()
print "Child process returned"
time.sleep(1)
在导入了NLTK的情况下运行它,您将看到urlopen()调用永远不会执行。 注释掉import nltk
行,它执行得很好。
为什么?
*编辑:这是针对Python 2的。我尚未在3上对其进行测试。
你有什么例外吗?
没有。 我在import urllib2; print...
周围放置了try .. except:
子句,但没有任何import urllib2; print...
。
我遇到了完全相同的问题。 我刚刚打开了一个SO问题,可能会在这里链接: http :
子进程确实无提示地崩溃,没有进一步通知。
我不同意你的@ oxymor0n ,对我来说这是一个严重的问题。 这基本上意味着,每当导入nltk时,就无法从子进程发出请求,这在使用API时确实很烦人。
The child process is indeed crashing silently without further notice.
我们还遇到以下问题的组合:nltk,gunicorn(通过预叉装载nltk)和长颈瓶。
删除nltk导入,一切正常。 除了nltk。
/ cc @escherba
@ ninowalker , @ oxymor0n奇怪的是,我的程序在代码中运行良好,得到了:
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content
Done
Child process returned
那是预期的输出,对吧?
这也不会破坏我的要求:
alvas<strong i="13">@ubi</strong>:~$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from multiprocessing import Process
>>> import requests
>>> from pprint import pprint
>>> Process(target=lambda: pprint(
... requests.get('https://api.github.com'))).start()
>>> <Response [200]>
>>> import nltk
>>> Process(target=lambda: pprint(
... requests.get('https://api.github.com'))).start()
>>> <Response [200]>
我正在使用:
我遇到了@Hiestaa遇到的相同问题。 我有导入nltk的帮助程序文件string_util.python,但是在使用多处理模块启动多进程搜寻器的主python文件中未使用该文件。 症状是子进程只是卡住了,没有错误消息(甚至没有异常消息)。
在注释掉与nltk相关的导入和功能后,问题得到解决。
细节:
作业系统:优胜美地10.10.5
的Python:2.7.10
检索页面内容:我最初使用urllib2,然后稍后切换到请求。
这是一个非常严重的错误,我希望有人可以介入并进行修复。 谢谢!
如果您要进行生产级NLP,我认为这是一个严重的问题。 我们正在使用Rq(http://python-rq.org/)工人来运行多个NLP管道,这在进行网络调用时会被无声地杀死。 希望很快会解决。 谢谢!
@sasinda :您可能想在nltk-dev邮件列表上打个电话,看看是否可以对此问题有所注意。
@sasinda我不确定Rq的工作原理,但是在我的生产级NLP项目中,我设法通过在单独且隔离的python解释器中启动每个进程来解决此问题,并使用Shell脚本在启动时生成它们。 在这种情况下,python永远不必派生,并且nltk的无提示崩溃永远不会发生。 也许这会有所帮助。
我发现在功能级别执行导入可以避免此问题。
换句话说,这有效:
def split(words):
import nltk
return nltk.word_tokenize(words)
这不是:
import nltk
def split(words):
return nltk.word_tokenize(words)
谢谢@mpenkov。 这样可以解决问题吗?
@stevenbird我不这么认为。 这是一种解决方法,但不是解决方法。
恕我直言,如果导入第三方库破坏了Python标准库组件,则某些地方发生了不正当的事情,需要对其进行修复。
@mpenkov我不完全确定为什么这样做,但是这是我发现有效的另一种解决方法。 在父进程中构建一个打开器似乎可以解决该问题。 修改@ oxymor0n的原始代码:
from multiprocessing import Process
import nltk
import time
import urllib2
# HACK
urllib2.build_opener(urllib2.HTTPHandler())
def child_fn():
print "Fetch URL"
import urllib2
print urllib2.urlopen("https://www.google.com").read()[:100]
print "Done"
while True:
child_process = Process(target=child_fn)
child_process.start()
child_process.join()
print "Child process returned"
time.sleep(1)
@mpenkov @ ninowalker , @ oxymor0n @sasinda @wenbowang你们仍然都面临着同样的问题吗?
我无法在我的机器上复制该问题:
from multiprocessing import Process
import nltk
import time
def child_fn():
print "Fetch URL"
import urllib2
print urllib2.urlopen("https://www.google.com").read()[:100]
print "Done"
while True:
child_process = Process(target=child_fn)
child_process.start()
child_process.join()
print "Child process returned"
time.sleep(1)
给我:
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-SG"><head><meta cont
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-SG"><head><meta cont
Done
Child process returned
Fetch URL
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-SG"><head><meta cont
Done
我上线了:
@alvations我发现这个问题已有很长时间了。
我什至忘记了哪个项目库存在此问题,所以我无法告诉您是否仍然存在此问题。
抱歉!
@alvations我也不记得我的哪个项目遭受了这个特定问题的困扰。
我在计算机上运行了您的代码,但无法复制该问题。
Python 2.7.12
nltk 3.2.1
macOS 10.12.6
@alvations我也不再从事该项目。 但是使用了这些解决方法之一。
我尝试了您的代码,但是对于我来说,子进程仍然以段错误(退出代码11)退出(退出行:urllib2.urlopen(“ https://www.google.com”).read()[:100])
它与urllib3(https://urllib3.readthedocs.io/en/latest/)一起使用。
据我所知,这个问题似乎影响了macOS。 到目前为止,使用Python 3.6
修改后的python3的OP脚本:
from multiprocessing import Process
import nltk
import time
def child_fn():
from urllib.request import urlopen
print("Fetch URL")
print(urlopen("https://www.google.com").read()[:100])
print("Done")
child_process = Process(target=child_fn)
child_process.start()
child_process.join()
print("Child process returned")
time.sleep(1)
输出:
Fetch URL
Child process returned
子流程意外退出,收到与此Stack Overflow post中类似的输出。
我认为这很令人困惑。 它可能与MacOS上的线程处理有关。
我对nltk并不是很熟悉,但是我四处张望,看看是什么导致测试通过/失败。 这是我必须对软件包__init__.py
进行的操作才能通过测试:
详细信息(单击以展开)
###########################################################
# TOP-LEVEL MODULES
###########################################################
# Import top-level functionality into top-level namespace
from nltk.collocations import *
from nltk.decorators import decorator, memoize
# from nltk.featstruct import *
# from nltk.grammar import *
from nltk.probability import *
from nltk.text import *
# from nltk.tree import *
from nltk.util import *
from nltk.jsontags import *
# ###########################################################
# # PACKAGES
# ###########################################################
# from nltk.chunk import *
# from nltk.classify import *
# from nltk.inference import *
from nltk.metrics import *
# from nltk.parse import *
# from nltk.tag import *
from nltk.tokenize import *
from nltk.translate import *
# from nltk.sem import *
# from nltk.stem import *
# Packages which can be lazily imported
# (a) we don't import *
# (b) they're slow to import or have run-time dependencies
# that can safely fail at run time
from nltk import lazyimport
app = lazyimport.LazyModule('nltk.app', locals(), globals())
chat = lazyimport.LazyModule('nltk.chat', locals(), globals())
corpus = lazyimport.LazyModule('nltk.corpus', locals(), globals())
draw = lazyimport.LazyModule('nltk.draw', locals(), globals())
toolbox = lazyimport.LazyModule('nltk.toolbox', locals(), globals())
# Optional loading
try:
import numpy
except ImportError:
pass
else:
from nltk import cluster
# from nltk.downloader import download, download_shell
# try:
# from six.moves import tkinter
# except ImportError:
# pass
# else:
# try:
# from nltk.downloader import download_gui
# except RuntimeError as e:
# import warnings
# warnings.warn("Corpus downloader GUI not loaded "
# "(RuntimeError during import: %s)" % str(e))
# explicitly import all top-level modules (ensuring
# they override the same names inadvertently imported
# from a subpackage)
# from nltk import ccg, chunk, classify, collocations
# from nltk import data, featstruct, grammar, help, inference, metrics
# from nltk import misc, parse, probability, sem, stem, wsd
# from nltk import tag, tbl, text, tokenize, translate, tree, treetransforms, util
有趣的是,所有残疾人进口最终都导致进口tkinter
,我认为这是根本原因。 如果在测试脚本中将import nltk
替换import tkinter
,则会得到非常相似的崩溃报告,都引用了tkinter。
据我所知,这些软件包直接导入tkinter
:
nltk.app
nltk.draw
nltk.sem
从上面对主包__init__
更改中,这些都是有问题的导入,以及它们追溯到导入tkinter的方式
nltk.featstruct
( sem
)nltk.grammar
( featstruct
)nltk.tree
( grammar
)nltk.chunk
( chunk.named_entity
> tree
)nltk.parse
( parse.bllip
> tree
)nltk.tag
( tag.stanford
> parse
)nltk.classify
( classify.senna
> tag
)nltk.inference
( inference.discourse
> sem
, tag
)nltk.stem
( stem.snowball
> corpus
> corpus.reader.timit
> tree
)感谢@rpkilby ,这非常有帮助!
我认为很长时间以来,叮叮当便一直是我们的痛点。 也许,如果我们能找到它的替代方法,那将会很好。
我同意。 较短期的解决方案是将tkinter导入埋入需要tkinter的类和方法中,并避免通过不需要它的程序导入它。 我们已经为numpy做过类似的事情。
最有用的评论
我对nltk并不是很熟悉,但是我四处张望,看看是什么导致测试通过/失败。 这是我必须对软件包
__init__.py
进行的操作才能通过测试:详细信息(单击以展开)
有趣的是,所有残疾人进口最终都导致进口
tkinter
,我认为这是根本原因。 如果在测试脚本中将import nltk
替换import tkinter
,则会得到非常相似的崩溃报告,都引用了tkinter。据我所知,这些软件包直接导入
tkinter
:nltk.app
nltk.draw
nltk.sem
从上面对主包
__init__
更改中,这些都是有问题的导入,以及它们追溯到导入tkinter的方式nltk.featstruct
(sem
)nltk.grammar
(featstruct
)nltk.tree
(grammar
)nltk.chunk
(chunk.named_entity
>tree
)nltk.parse
(parse.bllip
>tree
)nltk.tag
(tag.stanford
>parse
)nltk.classify
(classify.senna
>tag
)nltk.inference
(inference.discourse
>sem
,tag
)nltk.stem
(stem.snowball
>corpus
>corpus.reader.timit
>tree
)