Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python、多处理和GUI_Python_Python 2.7_Multiprocessing_Gtk3_Pygobject - Fatal编程技术网

Python、多处理和GUI

Python、多处理和GUI,python,python-2.7,multiprocessing,gtk3,pygobject,Python,Python 2.7,Multiprocessing,Gtk3,Pygobject,我有一个带有GUI的程序,需要进行一些多处理。其要点是避免冻结GUI,并允许用户在进程运行时使用其他一些按钮 然后我想定义一个如下所示的方法: def start_waiting(self, parent, func, args): self.window_waiting.show() task=Process(func(*args)) task.start() task.join() # Some code to execute at the e

我有一个带有GUI的程序,需要进行一些多处理。其要点是避免冻结GUI,并允许用户在进程运行时使用其他一些按钮

然后我想定义一个如下所示的方法:

def start_waiting(self, parent, func, args):

    self.window_waiting.show()

    task=Process(func(*args))
    task.start()

    task.join()

    # Some code to execute at the end of the process
    #
    #...
问题是
join()
不起作用,我需要它,因为
join()
之后执行的代码指示
进程的结束时间。我将使用该代码更新等待窗口的取消按钮

然后,我想到了另一种解决方案来避免使用
join()
,我将其替换为:

while task.is_alive():
    time.sleep(0.5)
但它也不起作用,所以我尝试了一个方案C,它是创建一个队列:

def worker(input, output):
    for func, args in iter(input.get, 'STOP'):
        result=func(*args)
        output.put(result)


task_queue = Queue()
done_queue = Queue()
task_queue.put(task)

Process(target=worker, args=(task_queue, done_queue)).start()
done_queue.get()
最后一个代码给了我错误:
'Pickling a AuthenticationString对象是'
TypeError:出于安全原因,不允许酸洗AuthenticationString对象


这让我想到了,但我还没有解决这个问题:/

您的第一个示例应该如下所示:

def start_waiting(self,parent,func,args):

    ...not relevant code..

    self.window_waiting.show()


    task=Process(target=func, args=args)  # This line is different.
    task.start()


    task.join()
def start_waiting(self,parent,func,args):

    ...not relevant code..

    self.window_waiting.show() # You should interact with the GUI in the main thread only.

    self.task = Process(target=func, args=args)  # This line is different.
    self.thrd = threading.Thread(target=self.start_and_wait_for_task)
    self.thrd.start()


def start_and_wait_for_task(self):
    """ This runs in its own thread, so it won't block the GUI. """
    self.task.start()
    self.task.join()
    # If you need to update the GUI at all here, use GLib.idle_add (see https://wiki.gnome.org/Projects/PyGObject/Threading)
    # This is required to safely update the GUI from outside the main thread.
按照您的方式,它实际上不是在子进程中执行
func
;它在父进程中执行它,然后将返回值传递给
进程
。调用
task.start()
时,它可能会立即失败,因为您传递的是
func
返回的内容,而不是函数对象

请注意,因为您正在调用
task.join()
内部
start\u waiting
,它可能会阻塞您的GUI,因为
start\u waiting
func
完成之前不会返回,即使它在子进程中运行。它不会阻塞的唯一方法是在GUI事件循环的单独线程中运行
start\u waiting
。你可能想要更像这样的东西:

def start_waiting(self,parent,func,args):

    ...not relevant code..

    self.window_waiting.show()


    task=Process(target=func, args=args)  # This line is different.
    task.start()


    task.join()
def start_waiting(self,parent,func,args):

    ...not relevant code..

    self.window_waiting.show() # You should interact with the GUI in the main thread only.

    self.task = Process(target=func, args=args)  # This line is different.
    self.thrd = threading.Thread(target=self.start_and_wait_for_task)
    self.thrd.start()


def start_and_wait_for_task(self):
    """ This runs in its own thread, so it won't block the GUI. """
    self.task.start()
    self.task.join()
    # If you need to update the GUI at all here, use GLib.idle_add (see https://wiki.gnome.org/Projects/PyGObject/Threading)
    # This is required to safely update the GUI from outside the main thread.

问题是join()函数不起作用
如何?@collone函数join()之后的代码在
任务
完成之前执行(我很难理解这一点,因为这是join()函数的滚动)。具体一点是没有坏处的。它也可能抛出错误或其他东西。@Yep上校,你说得对:)我刚刚尝试更改
task=Process(target=func,args=args)
,但我得到了相同的结果:/,谢谢你的提示,这解释了我以前遇到的问题。我仍然不知道如何实现这个GUI/多处理。你能看看我的节目吗?我刚开始编程,这真的很难解决>“在一个单独的线程中”我倾向于混淆线程和进程,我会好好看看。除了使用线程,我什么都试过了@rsm在
func
中发生了什么?你确定它不会因为某些原因而比你预期的更早失败或结束吗?我已经使用了
多处理。Process
很多次,而
join
的工作原理与它的预期完全一样。第一次它不工作(我不知道为什么,它应该像你说的那样工作,阻塞GUI)。相反,我按照您的建议创建了两个函数,并创建了第三个函数
change\u button
,其代码为`。。。只有在任务结束时才应该执行的代码…`我在join()之后添加了
GLib.idle\u add(change\u按钮)
,它工作得非常好@rsm您肯定不想尝试从子进程更新GUI!只要您使用GLib.idle\u add