Как говорит дружественный dogcow, чтобы запустить функцию в дочернем процессе, все, что вам нужно сделать используется multiprocessing.Process
:
p = multiprocessing.Process(target=f, args=('bob',))
p.start()
p.join()
Конечно, вы, вероятно, захотите повесить на p
и join
позже в большинстве случаев использования в реальных условиях. Вы, очевидно, не получаете никакого параллелизма, создавая новый процесс, чтобы заставить ваш основной процесс сидеть и ждать.
Таким образом, в вашем случае, это просто:
p = multiprocessing.Process(target=self.Connection, args=(args1, args2))
Но это, вероятно, не будет работать в вашем случае, потому что вы пытаетесь вызвать метод текущего self
объекта.
Прежде всего, в зависимости от вашей платформы и версии Python, multiprocessing
может передать связанный метод self.Connection
ребенку, протравив его и отправив его по трубе. Это включает в себя травление экземпляра self
, а также метод. Таким образом, он будет работать, только если MyFrame
объекты разборчивы. И я уверен, что wx.Frame
не может быть маринован.
И даже если вы сделать получить self
объект для ребенка, это, очевидно, будет копия, а не общий случай. Итак, когда метод Connection
дочернего процесса устанавливает self.connection = …
, это не повлияет на исходный родительский процесс self
.
Еще хуже, если вы попытаетесь позвонить любым wx.Frame
методам. Даже если все материалы Python работали, на большинстве платформ попытка изменить ресурсы GUI, такие как окна из неправильного процесса, не будет работать.
Единственные виды объектов, которые вы действительно можете разделить, - это виды, которые вы можете поместить в multiprocessing.Value
или multiprocessing.sharedctypes
.
Обойти это факторизовать код, который вы хотите childify в отдельную изолированную функцию, что акции как можно меньше (в идеале ничего, или почти ничего, кроме Queue
or Pipe
) с родителем.
Для примера, это легко:
class Client(object):
def connect_and_fetch(self):
self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connection.connect(('192.0.1.135' , 3345))
while True:
data = self.connection.recv(1024)
if not data:
break
else:
print data
def do_client():
client = Client()
connect_and_fetch()
class MyFrame(wx.Frame):
# ...
def Connection(self):
self.child = multiprocessing.Process(target=do_client)
self.child.start()
# and now put a self.child.join() somewhere
В самом деле, вам даже не нужен класс вообще здесь, потому что только у вас есть использование для self
для хранения переменной, которая может просто так же легко быть локальным. Но я предполагаю, что в вашей реальной программе, есть немного больше состояния, чем это.
Есть интересный (если немного устаревший) пример на wiki wxpython
, который называется MultiProcessing, который выглядит так, как будто он делает большую часть того, что вы хотите, и многое другое. (Это с помощью classmethod
для дочернего процесса, а не отдельной функции по какой-то причине, а также с использованием синтаксиса старого стиля для него, потому что это старое, но, надеюсь, это все-таки полезно.)
Если вы используете wx
для вашего графического интерфейса вы можете захотеть использовать свои механизмы межпроцессного взаимодействия вместо собственных Python. Хотя это сложнее и менее pythonic в общем случае, когда вы пытаетесь интегрировать дочерний процесс и его канал связи в свой основной цикл событий, почему бы не позволить wx
позаботиться об этом?
Альтернативой создать поток ждать на дочернем процессе и/или любой другой Pipe
или Queue
вы даете его, а затем создать и разместить wx.Event
сек в основной поток.
* Большинство, не все. Например, если f
временно использует большую часть памяти, ее запуск в дочернем процессе означает, что вы быстро освободите эту память для ОС. Или, если он вызывает плохо написанный сторонний/наследственный/любой код, который имеет неприятные и плохо документированные глобальные побочные эффекты, вы изолированы от этих побочных эффектов. И так далее.
, пожалуйста, приложите больше усилий, чтобы объяснить вашу проблему! – Moj
, вероятно, вы хотите запустить 'Connection' в фоновом * потоке * (не подпроцессе) и сообщить результаты в основной поток (GUI), используя' wx.CallAfter() '(см. [Long Running Tasks wiki] (http: // wiki.wxpython.org/LongRunningTasks)). – jfs