在Go中,编写非阻塞代码是否有意义?

| 从node.js的角度来看,所有代码都是非阻塞的。 在Go中,使用通道很容易实现无阻塞。 如果要在go中编写一个node.js类型的服务器,使其无阻塞是否有意义?例如,让数据库connect()函数返回一个通道,而不是等待连接发生时阻塞。 对我来说,这似乎是正确的方法 但是...     
已邀请:
        阻塞和非阻塞与性能无关,它们与接口有关。 如果您只有一个执行线程,则阻塞调用将阻止您的程序在等待时执行任何有用的工作。 但是,如果您有多个执行线程,则阻塞调用并不重要,因为您可以将该线程保持阻塞状态并在另一个线程中做有用的工作。 在Go中,当goroutine在I / O上阻塞时,它会换成另一个。 Go运行时使用非阻塞I / O系统调用来避免操作系统阻塞线程,因此可以在第一个线程等待I / O时在其上运行不同的goroutine。 Goroutine确实很便宜,因此不需要编写非阻塞样式的代码。     
        编写阻止功能。该语言使您可以轻松地将同步调用转换为异步调用。 如果要异步调用函数,请使用go语句。像这样:
c := make(chan bool)
go func() {
    blockingFunction()
    c <- true
}()

// do some other stuff here while the blocking function runs

// wait for the blocking function to finish if it hasn\'t already
<-c
    
        在Go中,系统调用是使用操作系统支持的最有效的基础机制以无阻塞方式实现的(例如
epoll
)。如果在等待调用结果时没有其他代码要运行,则它将阻塞线程(因为没有更好的事情要做),但是如果您有备用goroutines处于活动状态,则它们将改为运行。 回调(就像您以前在js中使用的一样)允许基本相同的底层机制,但是可以说程序员需要更多的心理体操。 在Go中,在函数调用之后立即指定要在函数调用之后运行的代码,而不是将其定义为回调。您希望与执行路径并行运行的代码应包装在goroutine中,并通过通道进行通信。     
        对于典型的Web服务器类型的应用程序,我建议不要使所有内容都异步。有几个原因。 与异步代码相比,对串行阻止代码进行推理更容易(更容易发现错误) golang错误处理基于defer(),panic()和restore(),使用100%异步代码可能无法提供所需的内容 如果您不小心,goroutines可能会泄漏[一个讨论]。您拥有的异步行为越多,就越难发现这些类型的问题,并且出现这些问题的可能性就越大。 一种策略是将异步性集中在一个较高的层次上,而其他所有事物都将受到阻碍。因此,您可能有一个\“数据库处理程序\” Blob,在逻辑上与\“请求处理程序\” Blob不同。它们都在单独的goroutine中运行,并使用通道进行通信。但是在“数据库处理程序”中,建立数据库连接和执行每个查询的调用是阻塞的。 您不必选择100%异步或0%异步。     
        阻塞接口总是比非阻塞接口更简单,更好。 Go的优点在于,它允许您以简单且易于推理的阻塞样式编写并发(和并行)代码。 非阻塞编程的方式都是由于人们使用的语言(特别是JavaScript)的不足,而不是因为非阻塞编程本质上是更好的。     

要回复问题请先登录注册