异步方法和线程之间有什么区别?

ser*_*off 5 multithreading asynchronous vala

有人可以解释异步方法和在Vala中创建线程之间的区别吗?我应该在我的代码中使用哪一个?

apm*_*ell 11

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方法.