从线程返回值
在 Python 中,如何让线程将元组或我选择的任何值返回给父级?
How do I get a thread to return a tuple or any value of my choice back to the parent in Python?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
我建议您在启动之前实例化一个 Queue.Queue线程,并将其作为线程的参数之一传递:在线程完成之前,它会将结果
.put
放在它作为参数接收的队列上。父级可以随意.get
或.get_nowait
。队列通常是在 Python 中安排线程同步和通信的最佳方式:它们本质上是线程安全的消息传递工具——通常是组织多任务处理的最佳方式!-)
I suggest you instantiate a Queue.Queue before starting the thread, and pass it as one of the thread's args: before the thread finishes, it
.put
s the result on the queue it received as an argument. The parent can.get
or.get_nowait
it at will.Queues are generally the best way to arrange thread synchronization and communication in Python: they're intrinsically thread-safe, message-passing vehicles -- the best way to organize multitasking in general!-)
您应该传递一个 Queue 实例作为参数,然后您应该将返回对象 .put() 放入队列中。无论您放置什么对象,您都可以通过queue.get()收集返回值。
示例:
用于多线程:
我使用这个实现,它对我来说非常有用。我希望你这样做。
You should pass a Queue instance as a parameter then you should .put() your return object into the queue. You can gather the return value via queue.get() whatever object you put.
Sample:
Use for multiple threads:
I use this implementation and it works great for me. I wish you do so.
使用lambda包装目标线程函数,并使用队列将其返回值传递回父线程。 (您的原始目标函数保持不变,无需额外的队列参数。)
示例代码:
输出:
Use lambda to wrap your target thread function and pass its return value back to the parent thread using a queue. (Your original target function remains unchanged without extra queue parameter.)
Sample code:
Output:
如果您调用 join() 来等待线程完成,您可以简单地将结果附加到 Thread 实例本身,然后在 join() 返回后从主线程检索它。
另一方面,您没有告诉我们您打算如何发现线程已完成并且结果可用。如果您已经有办法做到这一点,它可能会向您(以及我们,如果您要告诉我们的话)指出获得结果的最佳方法。
If you were calling join() to wait for the thread to complete, you could simply attach the result to the Thread instance itself and then retrieve it from the main thread after the join() returns.
On the other hand, you don't tell us how you intend to discover that the thread is done and that the result is available. If you already have a way of doing that, it will probably point you (and us, if you were to tell us) to the best way of getting the results out.
我很惊讶没有人提到你可以将它传递给一个可变的:
也许这有我不知道的重大问题。
I'm surprised nobody mentioned that you could just pass it a mutable:
perhaps this has major issues of which I'm unaware.
另一种方法是将回调函数传递给线程。这提供了一种简单、安全且灵活的方法,可以随时从新线程向父级返回值。
Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.
您可以使用同步 queue 模块。
考虑您需要从数据库中检查具有已知 ID 的用户信息:
现在您可以像这样获取数据:
You can use synchronised queue module.
Consider you need to check a user infos from database with a known id:
Now you can get your data like this:
对于简单的程序,上面的答案对我来说看起来有点矫枉过正。我会 en-nicen 可变方法:
For easy programs the above answeres look a little bit like overkill to me. I would en-nicen the mutable approach:
概念验证:
POC:
嗯,在 Python 线程模块中,有与锁关联的条件对象。一种方法
acquire()
将返回从底层方法返回的任何值。有关更多信息:Python 条件对象Well, in the Python threading module, there are condition objects that are associated to locks. One method
acquire()
will return whatever value is returned from the underlying method. For more information: Python Condition Objects基于 jcomeau_ictx 的建议。我遇到的最简单的一个。这里的要求是从服务器上运行的三个不同进程获取退出状态状态,并在三个进程都成功时触发另一个脚本。这似乎工作正常
Based on jcomeau_ictx's suggestion. The simplest one I came across. Requirement here was to get exit status staus from three different processes running on the server and trigger another script if all three are successful. This seems to be working fine
以下包装函数将包装现有函数并返回一个指向线程的对象(以便您可以调用
start()
、join()
等它)以及访问/查看其最终返回值。它看起来不错,并且
threading.Thread
类似乎很容易使用这种功能进行扩展(*),所以我想知道为什么它还不存在。上述方法有缺陷吗?(*) 请注意,husanu 对这个问题的回答正是这样做的,子类化
threading.Thread
产生了join()
给出返回值的版本。The following wrapper function will wrap an existing function and return an object which points both to the thread (so that you can call
start()
,join()
, etc. on it) as well as access/view its eventual return value.It looks OK, and the
threading.Thread
class seems to be easily extended(*) with this kind of functionality, so I'm wondering why it isn't already there. Is there a flaw with the above method?(*) Note that husanu's answer for this question does exactly this, subclassing
threading.Thread
resulting in a version wherejoin()
gives the return value.这是实现多线程的代码。
线程 1 正在将 10 到 20 之间的数字相加。
线程 2 正在将 21 到 30 之间的数字相加。
最后,输出返回到主程序,在那里它可以执行最终的加法。 (本程序中未显示)但您可以使用 numpy 调用。
Here is a code which implements multi-threading.
Thread 1 is adding numbers from 10 to 20.
Thread 2 is adding numbers from 21 to 30.
Finally the output is returned to the main program where it can perform final addition. (not shown in this program) but you can use a numpy call.
我认为 threading.Thread 子类化以更清晰的方式工作,因为结果仅与线程实例相关,而不求助于可能具有其他含义的其他对象(即队列)。
这是我的 2 美分示例:
Key 是子类线程的 run 方法,它将目标函数的返回值链接到线程的“结果”属性。简单明了。
I think the threading.Thread subclassing works in a more clear manner, given the fact that the result is tied only to the thread instance, without resorting to other objects (i.e. Queue) that may have other implications.
Here's my 2 cents example:
Key is run's method of subclassed thread, which links the return value of the target function to the 'result' attribute of the thread. Simple and straightforward.