Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 如何从异步方法/线程传递/交换数据?_Python_Multithreading_Python 2.7_Asynchronous - Fatal编程技术网

Python 如何从异步方法/线程传递/交换数据?

Python 如何从异步方法/线程传递/交换数据?,python,multithreading,python-2.7,asynchronous,Python,Multithreading,Python 2.7,Asynchronous,有人能解释一下python中如何在异步调用之间传递数据背后的概念吗 我有这样一个场景: 我有一个主过程(mainthread),然后运行另一个异步调用,添加两个数字()并休眠一段时间。我们的期望是让主线程等待计算和睡眠完成。就伪代码而言,可能如下所示: def example(): def my_calc(x,y): z = x+ y time.sleep(2) return z #this should get pushed to qu

有人能解释一下python中如何在异步调用之间传递数据背后的概念吗

我有这样一个场景:
我有一个主过程(mainthread),然后运行另一个异步调用,添加两个数字()并休眠一段时间。我们的期望是让主线程等待计算和睡眠完成。就伪代码而言,可能如下所示:

def example():
    def my_calc(x,y):
        z = x+ y
        time.sleep(2)
        return z  #this should get pushed to queue, but for simplicity we use 'return z'

    z = asyncSomething.callInThread(my_calc, 2, 20)  #assume we get z from queue
    return z+10

def runner():  #our main function
    print 'start'
    z = example()
    print 'result is {0}'.format(z)
如何使最后一次
打印
等待
z
?我尝试使用threading.Event()并播放了
set
wait
clear
,但它们阻止了一切

我不认为我的情况是独一无二的,必须有一个整洁系统的方式来做这件事。我查看了扭曲的反应堆,但部分成功。我的实际代码涉及GUI,它必须等待异步进程的结果,然后进行自我更新和自动更新……但我认为这个示例描述了大部分问题


我想我缺少了如何在python中异步工作的实际概念。

如果您使用多线程,那么应该使用来封装结果。具体来说,
future.result(timeout=None)
将用于您的情况:

返回调用返回的值。如果调用尚未完成,则此方法最多将等待
timeout
秒。如果调用在
timeout
秒内未完成,则将引发
concurrent.futures.TimeoutError
timeout
可以是
int
float
。如果未指定
超时
,则等待时间没有限制


如上所述,如果您没有使用多线程(并且正在使用异步编程),那么回调就是最好的选择。

如果您的主线程已经进展到了有意义的程度,而没有工作线程的结果,并且您想要阻止,您可以使用
threading.Event
等待工作线程执行中的某个点,也可以使用
thread.join
(其中
thread
threading.thread
实例)等待工作线程完成:

class Example(object):
    def my_calc(self, x, y):
        time.sleep(2)
        self._z = x + y # or push the result to a queue

    def example(self):
        thread = threading.Thread(target=self.my_calc, args=(2, 20))
        thread.start()
        # any other useful work could go here while the worker runs
        thread.join()
        return self._z + 10 # or grab the result from a queue

def runner():
    print "start"
    z = Example().example()
    print "result is {0}".format(z)
然而,在GUI的上下文中,主线程不太可能取得最大的进展——它可能一直忙于保持GUI的响应性。在这种情况下,正如在对问题的评论中所提到的,最好在辅助线程的计算完成后,将您想要完成的任何操作打包到一个回调中,以便辅助线程调用:

def my_calc(x, y):
    time.sleep(2)
    return x + y

def my_calc_thread(x, y, callback):
    z = my_calc(x, y)
    # depending on your GUI framework, you may need to do something
    # like call_in_main_thread(callback, z) if callback touches GUI
    # elements
    callback(z)

def example():
    def finish(z):
        print "result is {0}".format(z)
    t = threading.Thread(target=my_calc_thread, args=(2, 20, finish))
    t.start()

def runner():
    print "start"
    example()

您正在使用Python2吗?看起来Python3的async和await关键字在这里帮不上忙。\uz,它是2.7。我使用了“异步”这个比喻,而不是字面意思。2019年你使用python 2.7有什么原因吗?@opa,我工作的生态系统在2019年仍然使用2.7;因此我的问题我的主线程承载GUI ie GUI使用主线程。我在主线程外启动另一个帧(状态帧),它也在主线程中。在我们拥有的python风格中,我们只能将GUI启动到主线程中。然后我使用Twistedreactor让另一个线程同时执行calcs和更新状态帧。所有的工作,除了主线程似乎并没有等待扭曲线程(这是完全有意义的)。当我暂停主线程(via.wait())时,整个执行暂停(主线程和扭曲线程)——