Запуск процесса из многопроцессорного модуля Python и блокировки KIVY без ответа - PullRequest
0 голосов
/ 15 мая 2018

Эта простая программа работает некорректно, блокируя сообщение «Прочитать сообщение» после нажатия кнопки.Я думаю, что я не ошибаюсь в многопроцессорном коде, потому что я могу запустить этот код без kivy без проблем, но если я просто добавлю те же модули импорта из kivy, процесс перестанет возвращать любое значение.На самом деле мои тесты показывают, что процесс даже начинает работать.

Я сделал очень простой код, чтобы показать проблему.Вы можете просто скопировать и запустить.Когда я нажимаю кнопку test, программа немедленно блокируется, и основной поток не получает сообщение от процесса.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout


from multiprocessing import Process, Queue, Event

kv = '''
<InterfaceView>:
    Button:
        text: 'teste'
        on_press: root.do_process()
'''

def pprosess(message, q, stop):    
    q.put(message)    
    stop.wait()

Builder.load_string(kv)

class InterfaceView(BoxLayout):

    def do_process(self):
        q = Queue()
        stop = Event()

        p = Process(target=pprosess, args=('any message', q, stop))  
        p.daemon = True
        p.start()

        print('Read message')      
        print('message: ', q.get())

        stop.set()      
        p.join()

        print('Process closed')

class SimpleApp(App):
    def build(self):
        return InterfaceView()

if __name__ == '__main__':
    SimpleApp().run()  

Приведенный ниже код очень хорошо выполняет то же самое без kivy, поверьте мне или нет.Здесь вы можете увидеть правильный вывод терминала.

from multiprocessing import Process, Queue, Event

def pprosess(message, q, stop):    
    q.put(message)    
    stop.wait()

def main():
    q = Queue()
    stop = Event()

    p = Process(target=pprosess, args=('any message', q, stop))  
    p.daemon = True
    p.start()

    print('Read message')      
    print('message: ', q.get())

    stop.set()      
    p.join()

    print('Process closed')

if __name__ == '__main__':
    main()    

Я очень расстроен, борясь с этим в течение нескольких дней.Пожалуйста, кто-нибудь, помогите мне.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Моя проблема была связана со средой разработки Spyder и / или некоторыми ее компонентами.

Я использовал текущую консоль IPython для запуска своего кода, когда я переключился на выполнение на внешнем терминале , проблема была решена.

Спасибо @embryo и особенно @ikolim за помощь. Их тесты и предложения приводят меня к проблеме.

Итак, если вы используете Среда разработки Spyder , обратите внимание на плохие эффекты взаимодействия между Консоль IPython , многопроцессорным модулем Python и KIVY.

Все коды, которые я выложил, верны без проблем.

0 голосов
/ 15 мая 2018

Событие stop.wait() вызывает проблему.Это эквивалентно time.sleep ().Удаление stop должно исправить проблему.

Руководство по программированию »События и свойства» Основной цикл

В приложениях Kivy вы должны избегать длинных / бесконечныхциклы или спящие.

Пример

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout


from multiprocessing import Process, Queue, Event

kv = '''
<InterfaceView>:
    Button:
        text: 'teste'
        on_press: root.do_process()
'''


def pprosess(message, q):
    q.put(message)


Builder.load_string(kv)


class InterfaceView(BoxLayout):

    def do_process(self):
        q = Queue()

        p = Process(target=pprosess, args=('any message', q))
        p.daemon = True
        p.start()

        print('Read message')
        print('message: ', q.get())

        p.join()

        print('Process closed')


class SimpleApp(App):
    def build(self):
        return InterfaceView()


if __name__ == '__main__':
    SimpleApp().run()

Выход

Img01

...