【问题标题】:What's the difference between async methods and threads?异步方法和线程有什么区别?
【发布时间】:2015-01-10 19:47:14
【问题描述】:

谁能解释一下 async 方法和在 Vala 中创建线程有什么区别?我应该在我的代码中哪里使用一个或另一个?

【问题讨论】:

    标签: multithreading asynchronous vala


    【解决方案1】:

    线程是独立可调度的,async 方法运行在主线程中,即它们是协程。例如,如果您在单独的线程中阻止读取套接字,则应用程序可以继续运行,但如果您在 async 方法中执行此操作,则应用程序将被阻止。

    线程和协程(async 方法)可以解决一些相同的问题,但通常做不同的事情。在 Gtk+(和许多其他 GUI 系统)中,只有一个线程可以操作 GUI 对象,来自 GUI 对象的事件只会发生在这个线程中(通常称为事件调度线程)。如果另一个线程想要访问 GUI 项目,它要么需要 a) 执行一些锁定过程,要么 b) 向 EDT 发送消息。这概括了所有线程间通信:线程间通信或使用共享资源,需要锁定和通信。

    协程在 EDT 中作为“只是另一个事件”执行。考虑一种情况,您有一个带有下载按钮的窗口。当用户单击按钮时,EDT 将启动与按钮关联的单击处理程序。如果该代码实际尝试下载文件,则 GUI 将冻结,直到文件完成下载。如果启动了协程,则按钮的处理程序将启动 async 方法,该方法将打开一个套接字,然后被告知它尚未准备好。然后它将套接字和回调放入 EDT 的循环 (GLib.MainLoop)。按钮的处理程序将完成,EDT 将等待来自 X 显示器或套接字的事件,然后调用正确的回调来处理它。这允许以与套接字事件交错的方式处理 GUI 事件。但是,一次只能有一个处理程序在工作,因此处理程序需要能够快速完成,否则应用程序将无响应。

    使用协程会使回调变得一团糟,但是async 方法隐藏了回调,因此它看起来像直线代码,即使它不是。

    如果您的任务主要是在等待,那么协程是正确的选择。如果您的任务正忙于工作,那么它无疑需要进入一个线程。 Courotines 不能超过一个 CPU 的工作量,而线程可以在多个 CPU 上并行运行。 GLib 的协程也不容易与线程混合:尝试让 async 方法在两个线程中独立运行是不明智的:只有 EDT 可以使用 async 方法。

    【讨论】:

    • 由于这个帖子不是很受欢迎,我会允许我自己在 cmets 中感谢您!所以谢谢你
    猜你喜欢
    • 1970-01-01
    • 2016-04-13
    • 2018-12-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    相关资源
    最近更新 更多