Python 3.12 "Не удается создать новый поток при выключении интерпретатора" в межпроцессной связи из функции обработки заPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Python 3.12 "Не удается создать новый поток при выключении интерпретатора" в межпроцессной связи из функции обработки за

Сообщение Anonymous »

Системная проблема: < /p>
Windows 11
python: 3.12.1
matplotlib: 3.10.3
backend: 'tkagg'
Tkinter version: 8.6

У меня есть веб -приложение, в котором я использую Matplotlib, чтобы сгенерировать некоторые сюжеты и отображать их в браузере, и как часть интерфейса есть кнопка «интерактивная», которая отображает Windows Matplotlib windows Intervity. /> Поскольку графический интерфейс для отображения графиков требует, чтобы вызов был в основном цикле событий i
запустить отдельный процесс для отображения графиков Matplotlib и запустить дисплей, поместив
объект, который отображает графики на очередь - когда процесс графика получает такой объект из aever, он отображает таблицы. /># create cherrypy app and separate plot process
inputplotq = multiprocessing.Queue()
outputplotq = multiprocessing.Queue()

cpyapp = CPyApp(..., inputplotq, outputplotq)
plots_process = (
multiprocessing.Process(target=plot_process, args=(inputplotq,outputplotq), kwargs=keywords)
)

cherrypy.tree.mount(cpyapp)
cherrypy.engine.start()

# plotting process
def plot_process(inputplotq, outputplotq):

while not exit:
nextmsg = inputplotq.get()

if nextmsg is a plottingobj:
nextmsg.interactive_plot()
outputplotq.put("interactive windows clossed")
else
process command message

# cherry py app exposing method to generate plots
class CPyApp(..., inputplotq, outputplotq):
self.inputplotq = inputplotq
self.outputplotq = outputplotq

....

def genplots_interactive(**kwargs):
...
self.inputplotq.put(self.cachedplottingobj)
...
return self.cacheddoc

genplots_interactive.exposed = True
< /code>
Я изначально написал это на Linux с использованием: < /p>
python: 3.7.1
matplotlib: 3.4.0
backend: 'TkAgg'
Tkinter version: 8.6
< /code>
, который, кажется, работает нормально < /p>
, затем я выполнил работу в Windows, используя: < /p>
python: 3.12.1
matplotlib: 3.10.3
backend: 'tkagg'
Tkinter version: 8.6
< /code>
(я уверен, что разница связана с версией Python, но думал, что я упомянул, что это было в Windows в случае) < /p>
Когда я запускаю его, используя это вызов < /p>
self.inputplotq.put(self.cachedplottingobj)
< /code>
В методе приложения Cherry Py приводит к этому исключению: < /p>
Traceback (most recent call last):
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\site-packages\cherrypy\_cprequest.py", line 659, in respond
self._do_respond(path_info)
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\site-packages\cherrypy\_cprequest.py", line 718, in _do_respond
response.body = self.handler()
^^^^^^^^^^^^^^
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\site-packages\cherrypy\lib\encoding.py", line 223, in __call__
self.body = self.oldhandler(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\site-packages\cherrypy\_cpdispatch.py", line 54, in __call__
return self.callable(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\lc922756\ttrpython\ttrresultparsers\localwebserver\ttrresapp.py", line 946, in genplots_interactive
self._plots_queue.put(genplt)
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\queues.py", line 94, in put
self._start_thread()
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\queues.py", line 187, in _start_thread
self._thread.start()
File "C:\Users\lc922756\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 992, in start
_start_new_thread(self._bootstrap, ())
RuntimeError: can't create new thread at interpreter shutdown
< /code>
Я понимаю из своих поисков, что это новая функция защиты, добавленную в Python 3.12,
, но я немного смущен тем, что именно здесь происходит, и задавался вопросом, может ли кто -то пролить немного света? /> Любые идеи о том, где я должен смотреть или как я могу отлаживать это? Если это запускается, чтобы запустить процессы, а затем открывается страница в веб -браузере (Localhost: 8080), и кнопка «Interactive» нажимается, возникнет исключение.
Я замечаю, что исключение не возникает, когда я называю соединение () на процессе сюжета после запуска веб -сервера, но я запутался в том, почему мне нужно, чтобы это было, и то, что происходит под причинами, не приведенным в действие. />import time
import multiprocessing
import cherrypy
import matplotlib.pyplot as plt
import numpy

class MultiProcessInfo:
plots_process_queue = None
plots_op_queue = None
plots_process = None

def plot_process(plot_q, out_queue=None):
p_exit = False
print("plot_process starting")
while not p_exit:
print("plot_process: wait for plot generator or exit ...")
plot_generator = plot_q.get()
print(
f"====================================== plot_process: "
f"received plot_generator from q: {plot_generator}"
)
if plot_generator:
if isinstance(plot_generator, (str, bytes)):
if plot_generator == "exit":
print("plot_process: exiting")
p_exit = True
elif hasattr(plot_generator, "display_interactive"):
print("calling display_interactive")
plot_generator.display_interactive()
if out_queue:
out_queue.put("Interactive complete")
else:
print(f"plot_process message: {plot_generator}")
time.sleep(1)

class PlotGen:
def __init__(self):
self.xpoints = numpy.array([1, 8])
self.ypoints = numpy.array([3, 10])

def display_interactive(self):
plt.plot(self.xpoints, self.ypoints)
plt.show()

def genhtml(self):
pass

class CPyApp:
def __init__(self, inqueue, outqueue):
self.inqueue = inqueue
self.outqueue = outqueue

def index(self):
doc='
Test Page
'
formstr = ''
formstr += ''
formstr += ''
doc += formstr
doc += ''
return doc

def generate_interactive(self):
print("generate interactive")
plotgen = PlotGen()
# RuntimeError: can't create new thread at interpreter shutdown
# exception thrown with this call on windows/python 3.12,
# but not on centos 7/python 3.7.1
# (when join() is not called on plot_process after starting web server)
self.inqueue.put(plotgen)
return self.index()

index.exposed = True
generate_interactive.exposed = True

def start_plots_process():
plots_queue = multiprocessing.Queue()
plots_op_queue = multiprocessing.Queue()
plots_process = (
multiprocessing.Process(
target=plot_process, args=(plots_queue, plots_op_queue)
)
)
MultiProcessInfo.plots_process_queue = plots_queue
MultiProcessInfo.plots_op_queue = plots_op_queue
MultiProcessInfo.plots_process = plots_process
plots_process.start()

def start_web_server():
cherrypy.server.socket_host = '0.0.0.0'
cherrypy.config.update({"server.socket_port": 8080})
cherrypy.config.update({"server.nodelay": True})
cherrypy.config.update({"engine.autoreload.on": False})
cherrypy.config.update({"tools.sessions.on": True,})
cherrypy.config.update(
{"tools.encode.on": True, "tools.encode.encoding": "utf-8"}
)
theapp = CPyApp(
MultiProcessInfo.plots_process_queue,
MultiProcessInfo.plots_op_queue
)
cherrypy.tree.mount(theapp)
cherrypy.engine.start()

def main():
start_plots_process()
time.sleep(1)
start_web_server()
# if I uncomment this line exception is no longer thrown
# when running on windows/R3.12
#MultiProcessInfo.plots_process.join()

if __name__ == "__main__":
main()


Подробнее здесь: https://stackoverflow.com/questions/796 ... n-in-inter
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»