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

发布于 11-15 01:25 字数 198 浏览 4 评论 0原文

从 Node.js 的角度来看,所有代码都是非阻塞的。

在 Go 中,使用通道可以轻松实现非阻塞。

如果有人在 go 中编写一个 Node.js 类型的服务器,使其成为非阻塞是否有意义?例如,让数据库 connect() 函数返回一个通道,而不是在等待连接发生时阻塞。

对我来说,这似乎是正确的方法

,但是......

coming from node.js point of view, where all code is non-blocking.

In Go, non-blocking is easily achieved using channels.

if one were writing a node.js type server in go, does it make sense to make it non-blocking? for example, having a database connect() function return a channel, as versus blocking while waiting for the connection to occur.

to me, this seems the correct approach

but ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

挽清梦2024-11-22 01:25:09

阻塞和非阻塞实际上与性能无关,它们与接口有关。
如果您有一个执行线程,那么阻塞调用会阻止您的程序在等待时执行任何有用的工作。
但是,如果您有多个执行线程,则阻塞调用并不重要,因为您可以让该线程阻塞并在另一个线程中执行有用的工作。

在 Go 中,当一个 Goroutine 在 I/O 上阻塞时,它就会被替换为另一个 Goroutine。 Go 运行时使用非阻塞 I/O 系统调用来避免操作系统阻塞线程,以便在第一个 goroutine 等待 I/O 时可以在其上运行不同的 goroutine。

Goroutine 非常便宜,因此不需要编写非阻塞风格的代码。

Blocking and non-blocking aren't really about performance, they are about an interface.
If you have a single thread of execution then a blocking call prevents your program from doing any useful work while it's waiting.
But if you have multiple threads of execution a blocking call doesn't really matter because you can just leave that thread blocked and do useful work in another.

In Go, a goroutine is swapped out for another one when it blocks on I/O. The Go runtime uses non-blocking I/O syscalls to avoid the operating system blocking the thread so a different goroutine can be run on it while the first is waiting for it's I/O.

Goroutines are really cheap so writing non-blocking style code is not needed.

笑看君怀她人2024-11-22 01:25:09

编写阻塞函数。该语言允许您轻松地将同步调用转变为异步调用。

如果要异步调用函数,请使用 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

Write blocking functions. The language allows you to easily turn a synchronous call into an asynchronous one.

If you want to call a function asynchronously, use a go statement. Something like this:

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
锦爱2024-11-22 01:25:09

在Go中,系统调用是使用操作系统支持的最有效的底层机制(例如epoll)以非阻塞方式实现的。如果在等待调用结果时没有其他代码要运行,那么它会阻塞线程(因为没有更好的事情可做),但如果您有备用的 goroutine 处于活动状态,那么它们将会运行。

回调(正如您习惯在 js 中使用的那样)允许本质上相同的底层机制,但对于程序员来说可能需要更多的心理体操。

在 Go 中,在函数调用后运行的代码是在函数调用后立即指定的,而不是定义为回调。您想要与执行路径并行运行的代码应该包装在 goroutine 中,并通过通道进行通信。

In Go, system calls are implemented in a non-blocking way using the most efficient underlying mechanism that the OS supports (e.g. epoll). If you have no other code to run while you wait for the result of a call, then it blocks the thread (for lack of a better thing to do), but if you have alternate goroutines active, then they will run instead.

Callbacks (as you're used to using in js) allow for essentially the same underlying mechanics, but with arguably more mental gymnastics necessary for the programmer.

In Go, your code to run after a function call is specified immediately following the function call rather than defined as a callback. Code that you want to run parallel to an execution path should be wrapped in a goroutine, with communication through channels.

挽清梦2024-11-22 01:25:09

对于典型的 Web 服务器类型应用程序,我建议不要将所有内容都设为异步。有几个原因。

  • 比异步代码更容易推理串行阻塞代码(更容易看到错误)

  • golang 错误处理基于defer()、panic() 和recover(),这可能无法为您提供 100% 异步代码想要的东西

  • 如果你不小心,Goroutines 可能会泄漏[一个讨论]。异步行为越多,追踪这些类型的问题就越困难,而且它们出现的可能性就越大。

一种策略是将异步性集中在较高的级别上,而让其他一切都阻塞。因此,您可能有一个“数据库处理程序”blob,在逻辑上与“请求处理程序”blob 不同。它们都在单独的 goroutine 中运行并使用通道进行通信。但在“数据库处理程序”中,建立数据库连接和执行每个查询的调用是阻塞的。

您不必选择 100% 异步或 0% 异步。

For typical web-server type applications, I would recommend not making everything asynchronous. There are a few reasons.

  • It's easier to reason about serial blocking code than async code (easier to see bugs)

  • golang error handling is based on defer(), panic(), and recover(), which probably won't give you what you want with 100% asynchronous code

  • Goroutines can leak if you're not careful [one discussion]. The more async behavior you have, the harder it becomes to track down these types of problems and the more likely they are to show up.

One strategy is to focus the asynchonicity at a high level and leave everything else blocking. So you might have a "database handler" blob that is logically distinct from the "request handler" blob. They both run in separate goroutines and communicate using channels. But within the "database handler", the calls to establish a database connection and execute each query are blocking.

You don't have to choose 100% asynchronous or 0% asynchronous.

心在旅行2024-11-22 01:25:09

阻塞接口总是比非阻塞接口更简单、更好。 Go 的美妙之处在于它允许您以简单且易于推理的阻塞风格编写并发(和并行)代码。

非阻塞编程的流行完全是由于人们使用的语言(特别是 JavaScript)的缺陷,而不是因为非阻塞编程本质上更好。

Blocking interfaces are always simpler and better than non-blocking ones. The beauty of Go is that it allows you to write concurrent (and parallel) code in a simple, and easy to reason about, blocking style.

The fashion for non-blocking programming is all due to deficiencies in the languages people are using (specially JavaScript), not because non-blocking programming is intrinsically better.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文