.net Async和google go轻量级线程之间的主要区别是什么

sky*_*yde 21 .net c# asynchronous go .net-4.5

在运行中调用runtime.GOMAXPROCS(1)时,运行时只会为所有goroutine使用一个线程.当你做你的goroutines会产生并让其他goroutines在同一个线程上运行.

对于我来说,如果你不使用后台线程,.net异步CTP功能如何进行协同并发似乎非常相似.

我的问题是你能想到一种方法优于另一种方法的优点或缺点.

Krz*_*zyk 26

做出价值判断总是一件棘手的事情,所以我要强调3个不同之处.您决定它们是属于"专业"还是"骗局".

  1. 虽然Go和async都允许您以简单的方式编写异步代码,但在.NET中您必须知道代码的哪一部分是异步的,哪一部分不是(即您必须明确使用async/await关键字).在Go中你不需要知道 - 运行时使它"正常工作",没有特殊的语法来标记异步代码.

  2. Go design不需要标准库中的任何特殊代码..NET需要为每个异步操作向标准库添加新代码,基本上是针对这些情况的API表面加倍,例如,新的异步http下载API和旧的非异步http下载API必须保持向后兼容性.

  3. 设计和实施的规模要简单几个数量级.一小段运行时代码(调度程序)负责挂起阻塞系统调用并产生睡眠goroutine的goroutine.标准库中不需要任何特殊的异步支持.

.NET实现首先需要添加上述新API.此外,.NET实现基于编译器重写代码,异步/等待进入等效的状态机.它非常聪明但也相当复杂.实际结果是,第一个异步CTP已经知道了错误,而Go的实现从一开始就开始工作.

最终,它并不重要.async/await是在.NET中编写异步代码的最佳方法.Goroutines是Go的最佳方式.两者都很棒,特别是与大多数其他语言的替代品相比.

  • 我不确定我是否同意.您可以使用每个进程的线程(通道只是同步队列)在C#和Java中编写go-style goroutine.在许多情况下,您并不关心Go goroutine是在多个OS线程中进行多路复用的事实.C#async承诺某些代码将在同一个OS线程中运行,这对于UI线程的情况非常有用.你不能得到这样的承诺. (10认同)
  • @KrzysztofKowalczyk:我的最后一句话太苛刻了。我应该说“用 go 很难做到这一点”。来自 LockOSThread wiki:“Go 的运行时为此提供了 LockOSThread() 函数,但众所周知它很难正确使用”。Go 在背后管理操作系统线程,因此很难控制哪个函数在何处运行。通常这是一个好主意,但有时您关心哪些操作系统线程运行什么。我不明白我的评论有什么误导性。据我了解,C#'await 就像在 1 个线程上运行一组 goroutine。在 Go 中你不能那么容易地做到。http://bit.ly/13mxBG5 (2认同)