Обработка интенсивных событийных действий в Jython - PullRequest
0 голосов
/ 24 июня 2011

У меня есть некоторые долгосрочные процессы, которые должны происходить при заданных нажатиях кнопок или других событиях в графическом интерфейсе Jython, который я создаю.

В таких ситуациях, кажется, лучший вариант - это сделатьотдельный поток для запуска вызываемого метода / функции при возникновении события.

Каков наилучший способ сделать это?импортировать Threading и иметь класс, который я инициализирую и запускаю, когда actionPerformed?Использовать invokelater?Кажется, есть много способов сделать это, но лучше всего будет работать в среде Jython-Swing и быть самым быстрым?

start = JButton( "Analyze", actionPerformed = self.do_analysis )

def do_analysis(self):
    ...
    Large Time Consuming Task
    ...

Ответы [ 2 ]

1 голос
/ 25 июня 2011

Я не уверен на 100%, что у jython такая же проблема, но в C Python вы столкнетесь с проблемой с GIL или Global Interpreter Lock. Это будет означать, что, когда ваш фоновый поток работает, поток GUI не может запуститься (даже если он поставлен в очередь для запуска на другом ядре). Вы нажимаете кнопку, и ничего не происходит :(

Чтобы обойти это, я бы разделил длительный процесс на короткие шаги, которые можно запустить на событии, и поставил в очередь событие, чтобы начать следующий шаг по окончании текущего шага. Тогда графический интерфейс сможет работать между шагами, если это необходимо. Чем короче вы делаете шаги, тем более отзывчивым будет GUI - от 50 мс до 100 мс должно быть в порядке.

У этого подхода есть приятный побочный эффект: вам не нужно беспокоиться о потоках, блокировке, очереди сообщений или чем-либо еще. Вы можете попробовать добавить их в GUI, но события GUI и потоки могут бороться, что приводит к некоторым очень странным и трудным для отладки ошибкам.

Что касается "самых быстрых", то это, вероятно, самые низкие издержки для более коротких фоновых задач. Если вы создадите новый процесс для запуска фоновой задачи (очень большие издержки в Windows), он будет работать быстрее, потому что у него есть собственное ядро, но издержки запуска / остановки высоки.

0 голосов
/ 27 июня 2011

Это ситуация, когда вы получите лучшие результаты, помня, что Jython работает на JVM.Jython имеет полный доступ к классам Java, поэтому используйте API потоков Java для настройки отдельного потока вычислений.И если нагрузка на процессор достаточно высока, чтобы можно было использовать больше ядер, Java (jvm) позаботится об этом сама.

В некоторых случаях при длительных процессах люди использовали jstack -l дляполучите nids запущенных потоков, а затем используйте taskset для установки соответствия процессору.JVM nid находится в шестнадцатеричном формате и является PID процесса Linux, соответствующего потоку.Другие ОС могут иметь аналогичные возможности.

В общем, нет необходимости делать что-либо, кроме как сделать ваш Jython многопоточным.Если вы используете модуль потоков Python, у вас нет доступа к полному набору функций потоков Java, но он использует потоки JVM под капотом.Просто не забудьте ограничить свой доступ к глобальным переменным, иначе вы в конечном итоге создадите глобальную блокировку интерпретатора.Модуль очереди может помочь с этим.

...