У меня есть странная проблема. У меня есть двухпроцессорная аппликация, написанная на python и PySide для графического интерфейса.Пользовательский интерфейс Python не реагирует после долгого запуска
GUI запускается в первом потоке и разворачивает второй процесс (для предотвращения использования Python GIL), в котором запущена система измерения-statemachine. После запуска этот FSM отправляет сообщения через сокет в хост-приложение (для связи). Это время выполнения FSM часто очень длинное (5 часов).
Проблема в том, что каким-то образом приложение-хост становится невосприимчивым. Пользовательский интерфейс больше не обновляется (полученные сообщения от второго процесса больше не отображаются), а Windows говорит, что приложение не отвечает. Второй процесс все еще работает правильно.
Может ли кто-нибудь помочь мне отладить это? Это происходит только для очень длинных FSM и когда в FSM многое предстоит сделать. Может ли это быть общей проблемой ressource?
Редактировать: Код ниже firs t показывает метод выполнения потока, захватывающий сообщения от вторых процессов. Это вызывает обратный вызов, который определен ниже. Этот обратный вызов только испускает сигналы (и подает их с полученными данными) для обновления пользовательского интерфейса (например, для входа в пользовательский интерфейс).
class RunnerServer(QThread):
# ...
def run(self):
try:
self._socket.bind((self._host, 0))
self._port = self._socket.getsockname()[1]
self._is_started.set()
while not self._stop_event.is_set():
try:
data = self._socket.recvfrom(2048)[0]
except socket.error :
continue
if self._callback:
o = pickle.loads(data)
self._callback(o, *self._args, **self._kwargs)
except:
traceback.print_exc()
finally:
self._socket.close()
class Controller:
# ...
def remote_server_rx_callback(self, message, *args, **kwargs):
if isinstance(message, RunnerMessage):
self._sig_log_msg.emit(lmessage.message_type, message.message, message.source
elif isinstance(message, StatusMessage):
if message.message_type == StatusType.START:
self._sig_runner_started.emit()
elif message.message_type == StatusType.FINISH:
self._sig_runner_finished.emit()
elif message.message_type == StatusType.PROGRESS:
self._sig_runner_update_progress.emit(message.payload['progress'])
Не могли бы вы привести пример кода, который поможет вам выявить проблему? Иногда многопоточность с графическим интерфейсом сложна. –
@xndrme Я добавил некоторые фрагменты кода. – Razer
не видит ничего плохого в потоке против сигналов. Это происходит после того, как много сообщений журнала? Если вы удалите код, который запускает процесс, и замените материал сокета кодом, который снова и снова выдает одно и то же текстовое сообщение, вы видите одно и то же замедление? Сколько сообщений? – Schollii