作者:w50251898 | 来源:互联网 | 2022-12-07 00:37
我刚刚开始学习Go。Go的优势在于用于处理多个并发连接的goroutines。有人提到
Goroutine可以看作是轻量级线程(但实际上不是线程),它们可以增加/缩小堆栈大小,并且被复用为多个os线程。假设您有1000个goroutine,则根据goroutine的阻塞和等待模式将它们调度到本机OS线程。
基本上,我来自C#和Nodejs。我很困惑它与C#中实现的TaskParallelLibrary有何不同。
TaskParallelLibrary隐藏了创建线程和管理线程的复杂性。您只需启动任务,CLR就会将它们映射到本机线程。在这里您可以创建成千上万的微小任务,这些任务被映射并计划到OS线程。但是,TPL专门解决了异步问题。
我的问题是TPL与goroutines有何不同?goroutine是否使用协程(可暂停函数或?)。TPL还将async / syscalls操作复用到线程池,即使Go也将syscall复用到线程池。
如果我的任何假设是错误的,请纠正我。有人可以在确切的实现方式上有所帮助吗?为什么goroutines声称比TPL更快?
1> kostix..:
主要区别在于Go运行时将goroutine的调度与I / O紧密结合在一起,这基本上是这样的:如果goroutine即将在某些I / O操作或通道操作上阻塞,则调度程序会暂停该goroutine并重新执行一旦知道原始I / O或通道操作现在可以继续进行,就将其激活。这允许以纯顺序的方式编写Go代码-无需所有回调地狱和“未来” /“承诺”冲突,后者仅将回调包装到对象中,也无需async
/ machine,后者仅将await
编译器技巧与普通OS线程结合在一起。
Dart编程语言的开发人员之一在这篇经典文章中很好地解释了这些内容。
也看到这个和这个。
另一方面,async / await与特定的操作无关(如果Task不是正确的抽象,您甚至可以编写自己的awaitables),如果操作正确,那么最终不占用[所有线程](https://blog.stephencleary.com/2013/11/there-is-no-thread.html)。至少与C#中当前实现的一样。