Skip to content
CoolDesert edited this page Jun 20, 2023 · 6 revisions

由于 skynet 框架的消息处理使用了 coroutine ,所以不可以将 lua 原本的 coroutine api 直接和 skynet 服务混用。否则,skynet 的阻塞 API (见 LuaAPI)将调用 coroutine.yield 而使得用户写的 coroutine.resume 有不可预期的返回值,并打乱 skynet 框架本身的处理流程。

Because the Skynet framework uses coroutine to process messages, so it's not allowed to mix the use of the original coroutine API of Lua with Skynet services. Otherwise, the blocking API of Skynet (see LuaAPI) will call coroutine.yield and it will cause an unknown return from user-defined coroutine.resume and it will break the processing flow of the Skynet framework.

通常,你可以使用 skynet.forkskynet.waitskynet.wakeup 在 skynet 服务中创建用户级线程。

In general, you can use skynet.forkskynet.waitskynet.wakeup to create a user-level thread in the Skynet service.

如果你有其它原因想使用 coroutine ,那么可以使用 skynet.coroutine 模块。该模块的 API 含义和 Lua 原生的 coroutine 基本一致,所以一般可以这样使用:

If you have other reasons for using coroutine, try skynet.coroutine module. It contains API that has equal functionality to the original Lua API, and call it like this:

local coroutine = require "skynet.coroutine"

该模块增加了一个 API :

In this module, a new API gets added:

coroutine.thread(co) ,它返回两个值,第一个是该 co 是由哪个 skynet thread 间接调用的。如果 co 不是一个 skynet thread ,那么这个值和 coroutine.running() 一致,且第二个返回值为 true ,否则第二个返回值为 false 。这第二个返回值可以用于判断一个 co 是否是由 skynet.coroutine.createskynet.coroutine.wrap 创建出来的 coroutine 。

skynet.coroutine.thread(co) returns two values, the first one is the thread of indirect caller that invokes this co. If co is not a Skynet thread, it'll return the same value as coroutine.running() and the second value will be true, otherwise it'll return false. the second return value can be used to check if co is coming from skynet.coroutine.create or skynet.coroutine.wrap.

这里的 co 的默认值为 coroutine.running()

By default co is coroutine.running().

限制 Limitation

如果你没有调用 skynet.coroutine.resume 启动一个 skynet coroutine 而调用了 skynet.coroutine.yield 的话,会返回错误。

If you didn't call skynet.coroutine.resume to start a Skynet coroutine and you called skynet.coroutine.yield directly, it'll return an error.

你可以在不同的 skynet 线程(由 skynet.fork 创建,或由一条新的外部消息创建出的处理流程)中 resume 同一个 skynet coroutine 。但如果该 coroutine 是由 skynet 框架(通常是调用了 skynet 的阻塞 API)而不是 skynet.coroutine.yield 挂起的话,会被视为 normal 状态,resume 出错。

You can resume the same Skynet coroutine in different Skynet processes (thread created by skynet.fork or processing flow created by an external message). If this coroutine is suspended by the Skynet framework (usually by calling blocking API of Skynet) and not by skynet.coroutine.yield, it's treated as a normal state, resume in error.

注:对于挂起在 skynet 框架下的 coroutine ,skynet.coroutine.status 会返回 "blocked" 。

Note: for suspended coroutine in Skynet framework, skynet.coroutine.status will return "blocked".

Clone this wiki locally