1
55
Go有一个调度器,可以让您编写同步代码,自己进行上下文切换,并在幕后使用异步IO。因此,如果您正在运行多个goroutine,它们可能在单个系统线程上运行,并且当您的代码从goroutin的视图中阻塞时,它并不是真正阻塞。这不是魔法,但是的,它掩盖了所有这些东西。 调度器将在需要时分配系统线程,以及在真正阻塞的操作期间(例如,我认为文件IO正在阻塞,或者调用C代码)。但是,如果你正在做一些简单的http服务器,你可以使用几个“真正的线程”拥有成千上万的goroutine。 您可以在此处阅读有关Go内部工作的更多信息: |
2
36
你应该先阅读@Not_a_Golfer的答案和他提供的链接,以了解goroutines是如何安排的。我的回答更像是对网络IO的深入研究。我想你知道Go是如何实现协同多任务的。 Go可以而且确实只使用阻塞调用,因为所有东西都在goroutines中运行,它们不是真正的OS线程。它们是绿线。因此,您可以让它们中的许多都阻塞IO调用,并且它们不会像OS线程那样占用您的所有内存和CPU。
文件IO只是系统调用。高尔夫球手已经报道过了。Go将使用真正的OS线程来等待系统调用,并在返回时解锁goroutine。
Here
你可以看到文件
网络IO不同。运行时使用“网络轮询器”来确定哪个goroutine应该解除对IO调用的阻止。根据目标操作系统,它将使用可用的异步API来等待网络IO事件。调用看起来像是阻塞,但在内部所有操作都是异步完成的。
例如,当您呼叫
https://golang.org/src/net/fd_unix.go?s=#L237
当数据到达时,网络轮询器将返回应该恢复的goroutines。你可以看到
here
至于C#中的异步/等待。异步网络IO还将使用异步API(Windows上的IO完成端口)。当某些东西到达时,OS将在线程池的一个完成端口线程上执行回调,这将在当前线程上继续
|
Yomal · 在java中,如何知道线程池的任务何时结束 7 年前 |
Pissu Pusa · 实现非阻塞线程安全的单例日志记录类[关闭] 7 年前 |
duy · 在Spring 4中运行并行线程的优雅方式 7 年前 |
Roger Johansson · Golang阻塞和非阻塞 8 年前 |
latefreak · Python+Tornado用于会计软件 10 年前 |
canni · 如何将此代码转换为非阻塞和无锁代码? 10 年前 |
Mil0R3 · 回调未在Node.js中异步执行 11 年前 |