python - 如何从异步方法/线程传递/交换数据?
问题描述
有人可以解释如何在 python 中的异步调用之间传递数据背后的概念吗?
我有这种情况:
我有一个主过程(主线程),然后我运行另一个异步调用,它添加了两个 numbers() 并休眠了一段时间。期望是让主线程等到 calc 和 sleep 完成。就伪代码而言,这可能如下所示:
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)
我怎么做最后的print
等待z
?我尝试使用 threading.Event() 并使用set
、wait
和clear
,但它们阻止了一切。
我不认为我的案例是独一无二的,必须有一个整洁的系统方式来做这件事。我研究了扭曲的反应堆,但它部分成功。我的实际代码涉及 GUI,它必须等待异步进程的结果,然后进行自我和自动更新......但我认为这个例子描述了大部分问题
我想我错过了如何在 python 中异步工作的实际概念。
解决方案
如果您的主线程在没有来自工作线程的结果的情况下已经尽可能地进展并且您想要阻止,您可以使用 athreading.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()
推荐阅读
- python - 尝试 pip install dict 包时出现 docker build 错误
- pandas - 展平熊猫中的多索引
- postgresql - DataGrip SSL 错误:标签不匹配!javax.crypto.AEADBadTagException:标签不匹配
- microsoft-graph-api - 使用机器人录制 Microsoft Teams 会话(音频/视频/屏幕共享)
- visual-studio-code - WSL 不适用于 VS 代码。这里可能是什么问题?
- reactjs - 从嵌套列表中拖动项目时拖动后备项目的奇怪行为
- firewalld - 使用防火墙丰富的规则丢弃具有特定源和目标端口的环回数据包
- java - CXFServlet 抛出 java.lang.NoSuchMethodError:
- javascript - 计算 HTML 表单中的总行数
- swift - 在 UIKit 中模糊自定义 TabBar