Sejujurnya, masalah ini tidak seserius yang membuat penasaran. Saya telah menemukan bahwa ketika NLTK diimpor, itu akan menyebabkan subproses Python apa pun berhenti sebelum waktunya pada panggilan jaringan. Kode contoh:
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)
Jalankan dengan impor NLTK, dan Anda akan melihat bahwa panggilan urlopen () tidak pernah dijalankan. Komentari baris import nltk
, dan itu berjalan dengan baik.
Mengapa?
* edit: ini untuk Python 2. Saya belum mengujinya di 3.
Apakah Anda mendapatkan pengecualian?
tidak. saya meletakkan klausa try .. except:
sekitar import urllib2; print...
tetapi tidak mendapat apa-apa darinya.
Saya mengalami masalah yang sama persis. Saya baru saja membuka pertanyaan SO yang mungkin berguna untuk ditautkan di sini: http://stackoverflow.com/questions/30766419/python-child-process-silently-crashes-when-issuing-an-http-request
Proses anak ini memang berjalan diam-diam tanpa pemberitahuan lebih lanjut.
Saya tidak setuju dengan Anda @ oxymor0n , ini tampaknya masalah yang cukup serius bagi saya. Ini pada dasarnya berarti bahwa setiap kali nltk diimpor, tidak ada cara untuk mengeluarkan permintaan dari proses anak yang bisa sangat mengganggu saat bekerja dengan API.
The child process is indeed crashing silently without further notice.
Kami juga mengalami masalah ini dengan kombinasi dari: nltk, gunicorn (dengan nltk dimuat melalui prefork), dan flask.
Hapus impor nltk, dan semuanya bekerja. Kecuali nltk.
/ cc @escherba
@ninowalker , @ oxymor0n Aneh, proses saya berjalan dengan baik dengan kode, saya mendapatkan:
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
Itu hasil yang diharapkan, bukan?
Itu juga tidak merusak permintaan saya dengan ini:
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]>
Saya menggunakan:
Saya mengalami masalah yang sama dengan @Hiestaa . Saya memiliki file helper string_util.python yang mengimpor nltk, tetapi tidak digunakan dalam file python utama yang menggunakan modul multiprosesing untuk memulai crawler multi-proses. Gejalanya adalah proses anak hanya macet dan tidak ada pesan kesalahan (bahkan pesan pengecualian).
Setelah mengomentari impor dan fungsi terkait nltk, masalah tersebut teratasi.
Rincian:
OS: Yosemite 10.10.5
Python: 2.7.10
Ambil konten halaman: Saya menggunakan urllib2 pada awalnya, kemudian beralih ke permintaan nanti.
Ini adalah bug yang sangat serius, dan saya harap seseorang dapat turun tangan dan memperbaikinya. Terima kasih!
Saya pikir ini adalah masalah serius jika Anda melakukan NLP tingkat produksi. Kami menggunakan pekerja Rq (http://python-rq.org/), untuk menjalankan beberapa pipeline NLP, yang akan mati secara diam-diam saat melakukan panggilan jaringan. Semoga segera ada perbaikan. Terima kasih!
@sasinda : Anda mungkin ingin menghubungi milis nltk-dev untuk mengetahui apakah Anda dapat memperhatikan masalah ini.
@sasinda Saya tidak yakin bagaimana Rq bekerja dengan tepat tetapi dalam proyek NLP tingkat produksi saya, saya berhasil mengatasi masalah ini dengan memulai setiap proses dalam interpreter python yang terpisah dan terisolasi, menggunakan skrip shell untuk menelurkannya saat start-up. Dalam hal ini python tidak pernah harus bercabang dan crash diam-diam dari nltk tidak pernah terjadi. Mungkin ini bisa membantu sementara itu.
Saya telah menemukan bahwa melakukan impor pada tingkat fungsi menghindari masalah.
Dengan kata lain, ini berhasil:
def split(words):
import nltk
return nltk.word_tokenize(words)
dan ini tidak:
import nltk
def split(words):
return nltk.word_tokenize(words)
Terima kasih @mpenkov. Apakah ini menyelesaikan masalah?
@stevenbird Saya rasa tidak. Ini solusi, tapi itu bukan perbaikan.
IMHO, jika mengimpor pustaka pihak ketiga merusak komponen pustaka standar Python, sesuatu yang tidak suci terjadi di suatu tempat, dan perlu diperbaiki.
@mpenkov Saya tidak sepenuhnya yakin mengapa ini berhasil, tapi inilah solusi lain yang saya temukan berhasil. Membangun pembuka dalam proses induk tampaknya memperbaikinya. Memodifikasi kode asli @ 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 Apakah Anda semua masih menghadapi masalah yang sama?
Saya tidak dapat mereplikasi masalah di komputer saya:
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)
beri saya:
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
Aku di:
@alvations Sudah lama sekali saya tidak menemukan masalah ini.
Saya bahkan lupa basis proyek mana yang mengalami masalah ini, jadi saya tidak dapat memberi tahu Anda apakah saya masih mengalami masalah atau tidak.
Maaf!
@alvations Saya juga tidak ingat proyek mana yang mengalami masalah khusus ini.
Saya menjalankan kode Anda di komputer saya dan tidak dapat mereplikasi masalah.
Python 2.7.12
nltk 3.2.1
macOS 10.12.6
@alvations Saya juga tidak mengerjakan proyek itu lagi. Tetapi menggunakan salah satu solusi itu.
Saya mencoba kode Anda tetapi masih proses anak keluar dengan kesalahan segmen (kode keluar 11) untuk saya (keluar di baris: urllib2.urlopen ("https://www.google.com") .read () [: 100])
Ini bekerja dengan urllib3 (https://urllib3.readthedocs.io/en/latest/).
Sejauh yang saya tahu, masalah ini tampaknya memengaruhi macOS. Menggunakan Python 3.6 sejauh ini,
Skrip OP yang dimodifikasi untuk python3:
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)
Keluaran:
Fetch URL
Child process returned
Subproses berhenti tiba-tiba, menerima keluaran yang serupa dengan apa yang terlihat di pos Stack Overflow ini .
Saya pikir ini cukup membingungkan. Ini mungkin ada hubungannya dengan penanganan utas di MacOS.
Saya tidak terlalu familiar dengan nltk, tapi saya sedikit mengotak-atik untuk melihat apa yang menyebabkan tes lulus / gagal. Inilah yang harus saya lakukan pada paket __init__.py
agar tes lulus:
Detail (klik untuk memperluas)
###########################################################
# 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
Menariknya, semua impor yang dinonaktifkan pada akhirnya mengarah kembali ke impor tkinter
, yang menurut saya adalah akar masalahnya. Jika saya mengganti import nltk
dengan import tkinter
dalam skrip pengujian, saya mendapatkan laporan kerusakan yang sangat mirip, keduanya mereferensikan tkinter.
Dari apa yang saya tahu, paket-paket ini langsung mengimpor tkinter
:
nltk.app
nltk.draw
nltk.sem
Dari perubahan di atas ke paket utama __init__
, ini adalah impor bermasalah, dan bagaimana mereka menelusuri kembali ke pengimporan 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
)Terima kasih @rpkilby , itu sangat membantu!
Sepertinya masalah ini https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing
Saya pikir tinkter telah menjadi titik sakit bagi kami untuk beberapa waktu. Mungkin, akan lebih baik jika kita dapat menemukan alternatifnya.
Saya setuju. Solusi jangka pendek adalah mengubur impor tkinter di dalam kelas dan metode yang membutuhkan tkinter, dan menghindari mengimpornya oleh program yang tidak membutuhkannya. Kami telah melakukan sesuatu yang serupa untuk numpy.
Komentar yang paling membantu
Saya tidak terlalu familiar dengan nltk, tapi saya sedikit mengotak-atik untuk melihat apa yang menyebabkan tes lulus / gagal. Inilah yang harus saya lakukan pada paket
__init__.py
agar tes lulus:Detail (klik untuk memperluas)
Menariknya, semua impor yang dinonaktifkan pada akhirnya mengarah kembali ke impor
tkinter
, yang menurut saya adalah akar masalahnya. Jika saya menggantiimport nltk
denganimport tkinter
dalam skrip pengujian, saya mendapatkan laporan kerusakan yang sangat mirip, keduanya mereferensikan tkinter.Dari apa yang saya tahu, paket-paket ini langsung mengimpor
tkinter
:nltk.app
nltk.draw
nltk.sem
Dari perubahan di atas ke paket utama
__init__
, ini adalah impor bermasalah, dan bagaimana mereka menelusuri kembali ke pengimporan tkinternltk.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
)