Arhn - архитектура программирования

Как перенаправить функцию многопроцессорного пула

Я создаю текстовый виджет tkinter и хочу перенаправить sys.stdout на текстовый виджет. Частично я выполнил эту функцию, но столкнулся с проблемой многопроцессорности.

Ниже приведена игрушка Python 3, с которой вы можете играть,

import sys
import tkinter as tk
from multiprocessing import Pool

root = tk.Tk()
root.geometry('600x400+30+30')

textArea = tk.Text(root, bg='gray', width=70, height=20)
textArea.pack()
tk.Button(root, text='click me', command=lambda: print('Dont touch\n me!')).pack()

class redirectStd():
    def __init__(self, textWidget):
        self.textBoard = textWidget
        self.flush = sys.stdout.flush
    def write(self, msg):
        self.textBoard.insert('end', msg)

sys.stdout = redirectStd(textArea)
sys.stderr = redirectStd(textArea)

def f(x):
    print('calculate:', x, '** 2')
    return x ** 2

def testParallel():
    print('start testing')
    with Pool(processes=2) as p:
        res = p.map(f, [1, 4, 0, 7, 3, 5])
        print(res)

tk.Button(root, text='test multiprocessing', command=testParallel).pack()

root.mainloop()

Это будет работать правильно. Однако печать в def f(x) ничего не напечатает в текстовом виджете.

Если комментарий self.flush = sys.stdout.flush в блоке class redirectStd вызовет ошибку, которая жалуется на flush undefined в redirectStd. На данном этапе я не нашел, как определить метод flush для redirectStd. Полное сообщение об ошибке

start testing
Exception in Tkinter callback
Traceback (most recent call last):
  File "/Users/zsf/miniconda3/lib/python3.6/tkinter/__init__.py", line 1699, in __call__
    return self.func(*args)
  File "test.py", line 28, in testParallel
    with Pool(processes=2) as p:
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/context.py", line 119, in Pool
    context=self.get_context())
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/pool.py", line 168, in __init__
    self._repopulate_pool()
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/pool.py", line 233, in _repopulate_pool
    w.start()
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/process.py", line 105, in start
    self._popen = self._Popen(self)
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/context.py", line 277, in _Popen
    return Popen(process_obj)
  File "/Users/zsf/miniconda3/lib/python3.6/multiprocessing/popen_fork.py", line 17, in __init__
    sys.stdout.flush()
AttributeError: 'redirectStd' object has no attribute 'flush'

Может ли кто-нибудь дать намек на решение для этого? Спасибо!

04.08.2017

  • Переосмыслите свой подход, используйте IPC вместо перенаправлений. Ваша основная проблема заключается в том, что f — это отдельный процесс со своим собственным `Stdout. 04.08.2017

Ответы:


1

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

https://docs.python.org/2/library/multiprocessing.html https://docs.python.org/2/library/multiprocessing.html#multiprocessing-programming

Я решил вашу проблему немного по-другому, надеюсь, это поможет

import sys
import tkinter as tk
from multiprocessing import Pool


class redirectStd():
    def __init__(self, textWidget):
    self.textBoard = textWidget
    #self.flush = sys.stdout.flush
def write(self, msg):
    self.textBoard.insert('end', msg)

def f(x):
    print('calculate:', x, '** 2')
    return x ** 2

if __name__ == '__main__':

    root = tk.Tk()
    root.geometry('600x400+30+30')

    textArea = tk.Text(root, bg='gray', width=70, height=20)
    textArea.pack()
    tk.Button(root, text='click me', command=lambda: print('Dont touch\n me!')).pack()

    sys.stdout = redirectStd(textArea)
    sys.stderr = redirectStd(textArea)

    def testParallel():
        p = Pool(5)
        print(p.map(f, [10, 2, 3]))

    tk.Button(root, text='test multiprocessing', command=testParallel).pack()

    root.mainloop()
04.08.2017
  • Спасибо за ваше решение. Это все еще вызывает эту ошибку. Мне нужно раскомментировать #self.flush = sys.stdout.flush, чтобы он работал правильно. Однако print('calculate: ', x, '** 2') ничего не печатает. Есть ли у вас какие-либо дополнительные советы? Кстати, я тестирую это на macOS 10.12.6. 04.08.2017
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..