当前位置: 首页 > 知识库问答 >
问题:

Tarantool纤维与fiber.yield()和fiber.testcancel()的行为

汤英豪
2023-03-14

在构建基于光纤的塔兰托应用程序时,我遇到了一个意外的行为。

我的代码的简单复制器如下所示:

local log = require('log')
local fiber = require('fiber')

box.cfg{}

local func = function()
    for i = 1, 100000 do
        if pcall(fiber.testcancel) ~= true then
            return 1
        end

        fiber.yield()
    end

    return 0
end

local wrapfunc = function()
    local ok, resp = pcall(func)
    log.info(ok)
    log.info(resp)
end

for _ = 1, 100 do
    local myfiber = fiber.create(wrapfunc)
    fiber.sleep(0.02)
    fiber.kill(myfiber)
end

并打印到日志false,光纤被取消。此外,如果我使用以下func

local func = function()
    for i = 1, 100000 do
        if pcall(fiber.testcancel) ~= true then
            return 1
        end

        pcall(fiber.yield)
    end

    return 0
end

它打印到logtrue,1,如果我使用

local func = function()
    for i = 1, 100000 do
        if pcall(fiber.testcancel) ~= true then
            return 1
        end

        if pcall(fiber.yield) ~= true then
            return 2
        end
    end

    return 0
end

它打印到logtrue,2

我预计在运行myfiber后,如果控件返回到外部光纤并调用fiber.kill(myfiber),那么下次控件返回到取消的myfiber时,我们将进入循环迭代的末尾,在下一次迭代中,代码将成功返回1。但是,func的工作结束时抛出错误光纤被取消,而不是返回。那么,生产纤维的真实生命周期是如何运作的呢?

共有1个答案

岳奇逸
2023-03-14

事实上,这里没有意外的行为。我认为这主要是文件问题。让我解释一下。我将您的示例简化了一点:

#!/usr/bin/env tarantool

local fiber = require('fiber')

local f1 = function() fiber.yield() end
local f2 = function() pcall(fiber.yield) end

local func = function(fn)
    fn()
    if not pcall(fiber.testcancel) then
        return 'fiber.testcancel() failed'
    end
end

local fiber1 = fiber.create(function() print(pcall(func, f1)) end)
fiber.kill(fiber1)
local fiber2 = fiber.create(function() print(pcall(func, f2)) end)
fiber.kill(fiber2)

产出将是:

false   fiber is cancelled
true    fiber.testcancel() failed

调用fiber.kill时,fiber.yield()fiber.sleep()只会引发一个错误,因此您的光纤无法到达fiber.testcancel,就死掉了。当您执行pcall(fiber.yield)时,基本上可以抑制此错误并继续。然后fiber.testcancel检查其光纤状态并重新引发异常。但这是一个愚蠢的例子。

现在,对于较大的代码块,当涉及大量函数调用时,您通常希望在yield期间捕获这些错误,进行一些最终确定工作,并调用fiber.testcancel(),以向上提升错误(想象一下在big stacktrace的不同部分中进行的多个此类检查)。我相信这是最基本的用例,fiber.testcancel的引入是为了讨论它的设计是否可用。

是的,此类收益率通知的偶尔例外情况没有记录。至少我在光纤页面上找不到任何东西

 类似资料:
  • 我想创建一个test React应用程序,但我在安装时遇到了困难:我使用npm安装了Thread,因为Thread msi没有启动,所以: 我读了这个错误消息: 纱线产生v0。15.1错误:找不到包。C:\Users***\React中的json(或bower.json)文件位于C:\Users***\AppData\Roaming\npm\node\u modules\yarnpkg\lib\c

  • 我想知道,我怎么能设置回调光纤错误抛出。 例子: 我考虑在下次api访问时检查光纤:状态。或者创建一个光纤看门狗,如果我想要状态是有效的。这对我有用,但似乎不是最好的解决方案。

  • 我正在使用React Three Fiber和“Drei”,并想使用广告牌。但我只知道如何改变广告牌的颜色,而不知道如何添加纹理。 我试过这样做,但在广告牌上找不到任何文档,也不知道我能传递什么样的论点。 在这里,您可以看到如何更改颜色,但不能看到如何添加纹理: https://drei.react-spring.io/?path=/story/abstractions-布告牌——布告牌街 希望有

  • 情况: 3年来,有一个应用程序使用tarantool(现在是1.10.3),我们曾经决定将它移到Kubernetes,并替换旧的丑陋的dockerfile,基于Jessie的官方图像tarantool/tarantool:2.3.1。我不知道这些数据是否都可以。 在这种情况下,我有两个问题,我真的很乐意阅读你的正确答案: tarantool 2.3.1-2-g92750c828是否支持从taran

  • Tarantool 是一个用 Lua 语言编写的嵌入式 NoSQL 数据库,可以直接在 Lua 程序中运行。合并了 Node.js 的强大网络编程和 Redis 数据持久。 示例代码: #!/usr/bin/env tarantoolbox.cfg{}hosts = box.space.hostsif not hosts then    hosts = box.schema.create_spac

  • 本文向大家介绍光纤和铜线的比较,包括了光纤和铜线的比较的使用技巧和注意事项,需要的朋友参考一下 由于与传统的铜线相比具有许多优点,因此光缆的使用量正在增加。但是,其用法也有一些缺点。 光纤电缆比铜线的优势 光纤电缆传输数据的速度远高于铜线。这是因为光的速度大于电子的速度。 与铜线的10 Gbps带宽相比,光缆的带宽更大,超过60 Tbps。 光纤电缆的衰减非常低。中继器仅需每50公里添加一次,而铜