многопроцессорный процесс запускается непосредственно при создании - PullRequest
0 голосов
/ 22 мая 2019

Привет, у меня проблема с многопроцессорностью в Python 3.7 Я сделал слушатель, который должен ждать ответа от сервера, не блокируя остальную часть программы (асинхронная связь):

self = cl.appendSend('bar', base_list)
print("client erstellt neuen nebenläufigen listener, für die Antwort des Servers")
multiprocessing.set_start_method("spawn")
queue = multiprocessing.Queue()
process = multiprocessing.Process(target = cl.appendResponse(), args=(self))
process.start()
print("listener aktiv")

thread = threading.Thread(target= waitingPrinter(), args=(process, queue))
print(thread)

это где все запущено но строка process = multiprocessing.Process(target = cl.appendResponse(), args=(self)) запускается один раз, проходит через нее, а затем, после завершения, просто запускается снова. Отладчик никогда не покидает эту строку.

Метод, запущенный в процессе:

 def appendResponse(self):
        print("nebenläufiger listener aktiv")
        msgrcv = self.chan.receive_from(self.server)
        print("nebenläufiger listener hat Antwort erhalten")
        return msgrcv  # pass it to caller

К сожалению, из-за авторского права я не могу больше публиковать, но метод работает нормально в первый раз и завершается ошибкой с сообщением: Traceback (последний вызов был последним):

> File "D:/Verteile Systeme 2/neues Lab/git/vs2lab/lab2/rpc/runcl.py",
> line 27, in <module>
>     process = multiprocessing.Process(target = cl.appendResponse(), args=(self))   File "C:\Program Files
> (x86)\Python37-32\lib\multiprocessing\process.py", line 82, in
> __init__
>     self._args = tuple(args) TypeError: 'Client' object is not iterable

Так что мне интересно, почему процесс с cl.appendResponse() даже запускается после привязки к процессу и не ждет process.start(), и, если его еще нет в ответе, почему он запускается непосредственно секунду? время. И, конечно, как я могу это исправить.

Также есть ли способ заменить обработку потоком и получить возвращаемое значение? У меня много проблем с обработкой и возвратом значений.

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Причина очевидного немедленного выполнения процесса была правильно изложена Филиппом в их ответе .
Аргумент target для Process принимает вызываемый объект, который должен вызываться методом run(). Ваш код передает все, что возвращается self.chan.receive_from(self.server).
Подпроцесс не работает ни в строке, ни в строке process = multiprocessing.Process(target = cl.appendResponse(), args=(self)). Ваш метод выполняется в основном процессе и блокирует его.
На заметку: у вас будет точно такая же проблема с вашим thread по той же причине: thread = threading.Thread(target= waitingPrinter(), args=(process, queue))

После того, как ваш метод завершил выполнение в основном процессе, инициализация вашего объекта процесса вызывает TypeError внутри __init__ метода BaseProcess класса .
Вы передаете аргумент self своему процессу, но делаете это неправильно. Аргумент args требует кортежа аргументов. Создание кортежа через литерал требует запятой, если указано только одно значение: args=(self,). Ваш код эффективно передает self, то есть объект Client напрямую, который не повторяется и, следовательно, вызывает ошибку.
В вашем случае appendResponse представляется связанным методом объекта Client. Он получит аргумент self через внутреннюю работу системы классов Python. Явная передача его через процесс вызовет еще один TypeError для передачи двух позиционных аргументов методу, который принимает только один. Если appendSend не возвращает что-то еще, кроме Client экземпляра cl, для которого вы его вызываете, пропустите параметр args в экземпляре процесса.

С другой стороны, обратите внимание: метод запуска spawn является единственным, доступным в Windows, и, следовательно, по умолчанию. Если ваш код не должен работать под Unix с использованием этого метода запуска, эта строка является избыточной: multiprocessing.set_start_method("spawn")

1 голос
/ 22 мая 2019

target = cl.appendResponse() запустит функцию и вернет результат цели. Правильный синтаксис будет target=cl.appendResponse, который скажет Process запустить cl.appendResponse при запуске ().

...