SwiftNIO有没有类似GCD barrier的机制?
Does SwiftNIO have a mechanism similar to GCD barriers?
GCD 和 SwiftNIO 可以共存吗?
恕我无知。这让我很困惑。
推理:
- 线程过多不利于性能;
- GCD 创建并管理自己的线程;
- SwiftNIO 创建并管理自己的线程;
- 如果您使用许多不同的framework/library,每个都创建和管理各自的线程,您最终可能会得到太多线程;
我想要完成的事情:
我需要让多个独立的任务同时发生(由 SwiftNIO 处理),但偶尔,一旦所有先前的任务完成,运行 一个单一的串行任务(并且可能在此期间使用 SwiftNIO 默认为不同的行为时间)。为此,GCD 有 dispatch barriers,但据我所知,SwiftNIO 没有类似的机制。
是的,SwiftNIO 和 GCD 绝对可以共存。
SwiftNIO 是一个非阻塞和异步网络框架,因此您可以 运行 任意数量的 tasks/network 连接/...在极少数线程上。
事实上,您可以 运行 任何正确的 SwiftNIO 程序仅在 1 个线程上(如果您愿意,它甚至可以是主线程)并且它会工作得很好。甚至允许 SwiftNIO 使用多个线程的唯一原因是使用你支付的 CPU 资源。因此,例如,假设您正在实施一个网络服务器,该服务器应该同时处理 100,000 个连接,并且您的机器有 4 CPUs。您完全可以在一个线程上处理所有这 100,000 个连接,并且程序可以正常运行,但您只能使用四个可用核心之一。这会使程序不必要地变慢,并且您浪费了四个 CPU 核心。在这个例子中,我会建议生成一个具有 4 个线程的 EventLoopGroup
,然后 100,000 个连接将在四个循环中循环,这意味着每个循环(因此线程)应该获得大约 25,000 个连接并且您有机会使用所有可用的硬件资源。
关于您在其他一些操作成功后何时触发一个操作的其他问题:使用 SwiftNIO 时,您的操作可能类似于 func myOperation() -> EventLoopFuture<Void>
,现在假设您想要 运行 myOperation
并发100次然后打印“Hello World!”一旦他们都成功了。你在 NIO 中的做法是:
// Spawn `myOperation` 100 times, the array will contain 100 futures which
// will contain the result (or failure) of the 100 runs of `myOperation`.
let hundredOps = (0..<100).map { _ in
myOperation()
}
// Now we do the "barrier":
EventLoopFuture<Void>
// using `andAllSucceed` we create one future
// that will be fulfilled when all of the 100 futures from above are succeeded.
.andAllSucceed(hundredOps, on: eventLoop)
// And once that "overall future" is succeeded, we print "Hello World!"
.whenSuccess {
print("Hello World!")
}
GCD 和 SwiftNIO 可以共存吗?
恕我无知。这让我很困惑。
推理:
- 线程过多不利于性能;
- GCD 创建并管理自己的线程;
- SwiftNIO 创建并管理自己的线程;
- 如果您使用许多不同的framework/library,每个都创建和管理各自的线程,您最终可能会得到太多线程;
我想要完成的事情:
我需要让多个独立的任务同时发生(由 SwiftNIO 处理),但偶尔,一旦所有先前的任务完成,运行 一个单一的串行任务(并且可能在此期间使用 SwiftNIO 默认为不同的行为时间)。为此,GCD 有 dispatch barriers,但据我所知,SwiftNIO 没有类似的机制。
是的,SwiftNIO 和 GCD 绝对可以共存。
SwiftNIO 是一个非阻塞和异步网络框架,因此您可以 运行 任意数量的 tasks/network 连接/...在极少数线程上。
事实上,您可以 运行 任何正确的 SwiftNIO 程序仅在 1 个线程上(如果您愿意,它甚至可以是主线程)并且它会工作得很好。甚至允许 SwiftNIO 使用多个线程的唯一原因是使用你支付的 CPU 资源。因此,例如,假设您正在实施一个网络服务器,该服务器应该同时处理 100,000 个连接,并且您的机器有 4 CPUs。您完全可以在一个线程上处理所有这 100,000 个连接,并且程序可以正常运行,但您只能使用四个可用核心之一。这会使程序不必要地变慢,并且您浪费了四个 CPU 核心。在这个例子中,我会建议生成一个具有 4 个线程的 EventLoopGroup
,然后 100,000 个连接将在四个循环中循环,这意味着每个循环(因此线程)应该获得大约 25,000 个连接并且您有机会使用所有可用的硬件资源。
关于您在其他一些操作成功后何时触发一个操作的其他问题:使用 SwiftNIO 时,您的操作可能类似于 func myOperation() -> EventLoopFuture<Void>
,现在假设您想要 运行 myOperation
并发100次然后打印“Hello World!”一旦他们都成功了。你在 NIO 中的做法是:
// Spawn `myOperation` 100 times, the array will contain 100 futures which
// will contain the result (or failure) of the 100 runs of `myOperation`.
let hundredOps = (0..<100).map { _ in
myOperation()
}
// Now we do the "barrier":
EventLoopFuture<Void>
// using `andAllSucceed` we create one future
// that will be fulfilled when all of the 100 futures from above are succeeded.
.andAllSucceed(hundredOps, on: eventLoop)
// And once that "overall future" is succeeded, we print "Hello World!"
.whenSuccess {
print("Hello World!")
}