skynet笔记

1、skynet.newservice和skynet.uniqueservice的区别

skynet.newservice:

  • 当调用skynet.newservice时,它会每次都创建一个新的服务实例,即使之前已经存在相同类型的服务实例。
  • 这意味着可以同时启动多个相同类型的服务实例,它们之间是相互独立的。
  • local service1 = skynet.newservice("my_service")
    local service2 = skynet.newservice("my_service")
    

 skynet.uniqueservice:

  • 调用skynet.uniqueservice时,它会检查是否已经存在相同类型的服务实例。如果已经存在,则返回已存在的服务实例的句柄,而不会启动新的实例。
  • 这确保了同一类型的服务只有一个实例在运行。
  • local service1 = skynet.uniqueservice("my_service")
    local service2 = skynet.uniqueservice("my_service") -- 返回与service1相同的句柄
    

2、skynet.core.pack(...)接口的作用

该函数是用于将一组 Lua 值打包成一个二进制字符串的接口。这个接口在底层用于消息的序列化和打包,通常在网络传输、进程间通信等场景中使用。

具体来说,pack 函数接受一组 Lua 值作为参数,并返回一个包含了这些值的二进制字符串。这个字符串可以通过网络或其他方式传递给其他服务或系统组件。

例如:

local c = require "skynet.core"local data = c.pack(42, "hello", {1, 2, 3})-- 将 data 发送给其他服务,用于消息传递或通信

在上述例子中,pack 将整数 42、字符串 "hello" 和一个包含数字的数组打包成一个二进制字符串,并将其存储在变量 data 中。

在 Skynet 中,这样的打包操作常常用于将消息序列化,以便通过网络或消息队列传递给其他 Skynet 服务。反之,unpack 函数用于将这样的二进制字符串反序列化为 Lua 值。

请注意,packunpack 通常是 Skynet 框架内部使用的底层接口。在一般的 Skynet 服务代码中,您更可能会使用高级的接口,如 skynet.sendskynet.call,它们会自动处理消息的序列化和反序列化。

3、协程的状态

在Skynet框架中,协程状态的概念通常与消息处理和异步操作密切相关。Skynet使用协程的方式实现了一种事件驱动的异步编程模型。除了"SUSPEND"状态之外,Skynet还定义了其他一些状态,它们对应于协程在不同的事件和阶段的处理。

以下是一些常见的协程状态:

  1. "SUSPEND":表示协程被挂起,通常是因为它正在等待某个事件的发生或在执行异步操作。在这个状态下,协程通过coroutine.yield("SUSPEND")挂起,等待外部事件或其他协程的唤醒。

  2. "RUNNING":表示协程正在运行中,即处于活动状态。协程会在处理消息或执行其他任务时处于这个状态。通常,协程在运行中时不会被挂起。

  3. "DEAD":表示协程已经终止或结束。协程在执行完任务后,或者在发生错误时可能会进入这个状态。已经结束的协程不再可用。

这些状态反映了协程在消息处理过程中的生命周期。在Skynet框架中,通过coroutine.yield传递不同的状态,可以实现协程的挂起和恢复,以及在不同的状态下执行相应的处理逻辑。状态的具体用途可能因具体的业务逻辑而有所不同。

4、local c = require "skynet.core";c.callback();这个callback是干嘛用的

在 Skynet 框架中,c.callback() 是用于注册一个 C 函数(Callback Function)到 Skynet 的底层事件循环中的回调队列中。这样,当 Skynet 的事件循环需要执行回调函数时,它就会调用注册的 C 函数。

通常情况下,c.callback() 会在 C 模块的初始化部分调用,用于注册一些与底层事件循环相关的回调函数。这些回调函数可能用于处理网络事件、定时器、IO 等底层的异步操作。

这个函数的具体用途和效果可能依赖于具体的 Skynet 模块或 C 拓展,因为 Skynet 的底层是使用 C 实现的,并且提供了一些 C API 来与 Lua 交互。在 Skynet 的源码或相关文档中,可能会有详细的说明和用法示例。

总的来说,c.callback() 的作用是将一个 C 函数注册为 Skynet 事件循环的回调,以便在事件发生时执行这个 C 函数。如果您想了解具体的用法和效果,建议查阅 Skynet 的源码或文档。

5、启动一个子服务,具体要经历哪些步骤?

下面以一个wsgate为例

  1. 在etc文件夹下面找到config文件,里面的start = "main"说明你的程序的入口是main.lua
  2. 在main.lua中输入以下代码,启动一个叫wsgate的服务(当然前提是你要有wsgate.lua文件)
    local gate = skynet.uniqueservice("wsgate")  -- 启动一个服务器实例,并返回句柄

     3. 接着进入uniqueservice接口,发现里面是调用skynet.call

function skynet.uniqueservice(global, ...)if global == true thenreturn assert(skynet.call(".service", "lua", "GLAUNCH", ...))elsereturn assert(skynet.call(".service", "lua", "LAUNCH", global, ...))  -- 调用.call的时候,会把“LAUNCH”以及后面的数据打包发到底层C语言中去处理,C里面通过LAUNCH映射到cmd_launchend
end

     4.进入skynet.call,第一个if是判断要不要打印,这个无伤大雅先不管他;然后再去调用auxsend这个函数和下面的挂起协程

function skynet.call(addr, typename, ...)local tag = session_coroutine_tracetag[running_thread]if tag thenc.trace(tag, "call", 2)c.send(addr, skynet.PTYPE_TRACE, 0, tag)endlocal p = proto[typename]local session = auxsend(addr, p.id , p.pack(...))  -- auxsend接口:调用c.cend接口发送消息(其次做了会话冲突处理)if session == nil thenerror("call to invalid address " .. skynet.address(addr))endreturn p.unpack(yield_call(addr, session))   -- 挂起协程
end

    5.现在去看下auxsend这个函数,这段代码比较长

  1. dangerzone 是一个用于标记处于 "danger zone" 区域的集合,这个区域是一个会随着会话(session)递增而重新设置的区域。这里的 "danger zone" 是为了防止会话的递增与之前的某些会话发生冲突。
  2. set_checkrewindset_checkconflict 是用于设置 auxsendauxtimeout 的辅助函数,根据当前的会话范围选择合适的函数。
  3. checkconflict 函数用于检查会话是否存在冲突,即下一个会话是否已经存在。如果存在冲突,将会进行相应的处理,可能会调整 auxsendauxtimeout 的实现,以确保不发生会话冲突。
  4. auxsend_checkconflictauxtimeout_checkconflict 以及 auxsend_checkrewindauxtimeout_checkrewind 是根据当前会话范围选择的具体的消息发送和超时设置的函数。它们会在发送消息或设置超时时检查是否存在冲突,如果存在冲突,则会进行相应的处理。
  5. 初始时,auxsendauxtimeout 被设置为 auxsend_checkrewindauxtimeout_checkrewind,表示在最初的 "safe zone" 区域中。

        总体来说,这段代码的目的是为了管理会话(session)的递增,并根据当前会话范围的不同来选择适当的消息发送和超时设置的实现。这有助于防止会话冲突,并在需要时进行相应的处理。

然后auxsend会被设置成auxsend_checkconflict或者auxsend_checkrewind,在这两个接口中调用csend接口调用skynet.core底层中的send函数。

TODO:至于为什么要做会话冲突处理,我的理解是怕每个会话的地址重复了,这个理解的还不是很到位,以后理解了再做补充。还有就是send到C语言那边是怎么做处理的,这个以后有空再补充

do ---- avoid session rewind conflictlocal csend = c.sendlocal cintcommand = c.intcommandlocal dangerzonelocal dangerzone_size = 0x1000local dangerzone_low = 0x70000000local dangerzone_up	= dangerzone_low + dangerzone_sizelocal set_checkrewind	-- set auxsend and auxtimeout for safezonelocal set_checkconflict -- set auxsend and auxtimeout for dangerzonelocal function reset_dangerzone(session)dangerzone_up = sessiondangerzone_low = sessiondangerzone = { [session] = true }for s in pairs(session_id_coroutine) doif s < dangerzone_low thendangerzone_low = selseif s > dangerzone_up thendangerzone_up = senddangerzone[s] = trueenddangerzone_low = dangerzone_low - dangerzone_sizeend-- in dangerzone, we should check if the next session already exist.-- 检查会话是否存在冲突,即下一个会话是否已经存在。如果存在冲突,将会进行相应的处理,可能会调整 auxsend 和 auxtimeout 的实现,以确保不发生会话冲突。local function checkconflict(session)if session == nil thenreturnendlocal next_session = session + 1if next_session > dangerzone_up then-- leave dangerzonereset_dangerzone(session)assert(next_session > dangerzone_up)set_checkrewind()elsewhile true doif not dangerzone[next_session] thenbreakendif not session_id_coroutine[next_session] thenreset_dangerzone(session)breakend-- skip the session already exist.next_session = c.genid() + 1endend-- session will rewind after 0x7fffffffif next_session == 0x80000000 and dangerzone[1] thenassert(c.genid() == 1)return checkconflict(1)endendlocal function auxsend_checkconflict(addr, proto, msg, sz)local session = csend(addr, proto, nil, msg, sz)checkconflict(session)return sessionendlocal function auxtimeout_checkconflict(timeout)local session = cintcommand("TIMEOUT", timeout)checkconflict(session)return sessionendlocal function auxsend_checkrewind(addr, proto, msg, sz)local session = csend(addr, proto, nil, msg, sz)if session and session > dangerzone_low and session <= dangerzone_up then-- enter dangerzoneset_checkconflict(session)endreturn sessionendlocal function auxtimeout_checkrewind(timeout)local session = cintcommand("TIMEOUT", timeout)if session and session > dangerzone_low and session <= dangerzone_up then-- enter dangerzoneset_checkconflict(session)endreturn sessionendset_checkrewind = function()auxsend = auxsend_checkrewindauxtimeout = auxtimeout_checkrewindendset_checkconflict = function(session)reset_dangerzone(session)auxsend = auxsend_checkconflictauxtimeout = auxtimeout_checkconflictend-- in safezone at the beginning-- 默认是将auxsend设置成auxsend_checkrewindset_checkrewind()
end

        6.yield_call里面主要是将这个协程挂起,等待

local function yield_call(service, session)watching_session[session] = servicesession_id_coroutine[session] = running_threadlocal succ, msg, sz = coroutine_yield "SUSPEND"watching_session[session] = nilif not succ thenerror "call failed"endreturn msg,sz
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/227623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot的高校教学评价系统的设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于Springboot的高校教…

【C++】std::bind与functional函数对象

functional 文章目录 functionalstd::bind使用示例 std::function类模板成员函数使用推导指引(C17 起) std::bind 原型&#xff1a; template< class R, class F, class... Args > constexpr /* 未指定 */ bind( F&& f, Args&&... args );函数模板 std…

如何通过TortoiseGit可视化工具查看Git管理的版本树和信息(工作树变更)内容

一、版本树 黑色直线&#xff1a;master分支和基于master分支拉取基础分支都在这条线上&#xff0c;是一条直线。 其他线条&#xff1a;新开分支一定会增加一条线&#xff0c;但不一定每一条线分别代表一个分支。 注&#xff1a;如果一直是一个人&#xff0c;在同一个本地分支…

(三)Java 基本数据类型

目录 一. 前言 二. 基本数据类型 2.1. char&#xff08;字符型&#xff09; 2.2. byte&#xff08;字节型&#xff09; 2.3. short&#xff08;短整型&#xff09; 2.4. int&#xff08;整型&#xff09; 2.5. long&#xff08;长整型&#xff09; 2.6. float&#xff…

powerbuilder游标的使⽤

在某些PowerBuilder应⽤程序的开发中,您可能根本⽤不到游标这样⼀个对象。因为在其它⼯具开发中很多需⽤游标实现的⼯作,在PowerBuilder中却已有DataWin-dow来代劳了。事实上,DataWindow不仅可以替代游标进⾏从后台数据库查询多条记录的复杂操作,⽽且还远不⽌这些。但是同DataW…

前端如何设置模板参数

1.背景&#xff1a; 最近接到一个需求&#xff0c;在一个类似chatGpt的聊天工具中&#xff0c;要在对话框中设置模板&#xff0c;后端提供了很多模板参数&#xff0c;然后要求将后端返回的特殊字符转成按钮&#xff0c;编辑完成后在相应的位置拼接成字符串。 2.效果&#xff1a…

C++ 类模板

目录 前言 类模板语法 类模板和函数模板的区别 类模板没有自动类型推导的使用方式 类模板在模板参数列表中可以有默认参数 类模板中成员函数创建时机 类模板对象做函数参数 指定传入的类型 参数模板化 整个类模板化 类模板与继承 类模板成员函数类外实现 类模板分…

在Spring Cloud中使用OpenFeign完成从一个微服务上传到另一个微服务中

跨服务上传文件&#xff0c;嘿嘿&#xff0c;来一篇实用性高的&#xff0c;本篇将主要完成在Feign中上传文件到另一个微服务中。步骤如下&#xff1a; 我们需要在服务提供者和服务消费者的项目中添加相应的依赖&#xff1a; 对于服务提供者的项目&#xff0c;你需要添加Sprin…

Redis设计与实现之集合及有序集

目录 一、集合 1、编码的选择 2、编码的切换 3、 字典编码的集合 4、集合命令的实现 5、 求交集算法 6、求并集算法 7、 求差集算法 二、有序集 1、编码的选择 2、编码的转换 3、ZIPLIST 编码的有序集 4、SKIPLIST 编码的有序集 三、如何添加元素到集合或有序集中…

Next.js 学习笔记(二)——项目结构

Next.js 项目结构 此页面提供了 Next.js 项目的文件和文件夹结构的概述。它涵盖了 app 和 pages 目录中的顶级文件和文件夹、配置文件以及路由约定。 顶级文件夹 文件夹名描述appApp RouterpagesPages Routerpublic待服务的静态资源src可选的应用程序源文件夹 顶级文件 文…

万兆网络之屏蔽线序接法(中)

在介绍优质网线选购之前&#xff0c;先简单介绍一下水晶头 1毛钱一颗跟1元一颗的水晶头&#xff0c;往往是金手指厚度差别&#xff0c;你可以想象压制的时候可能会有什么情况 另外&#xff0c;一些3元一颗的镀金水晶头会有15U、30U之类的是电镀厚度单位&#xff0c;数值越大镀…

React Native面试题总结

1,简单介绍下React Native,以及和React.js的区别 React Native是一个JavaScript框架,由Facebook开发,以满足日益增长的移动应用开发的需求。它是开源的,基于JavaScript的。它被设计为用可重复使用的组件构建本地移动应用程序。它使用了大量的ReactJS组件,但在不同的设备…

文档安全加固:零容忍盗窃,如何有效预防重要信息外泄

文档安全保护不仅需要从源头着手&#xff0c;杜绝文档在使用和传播过程中产生的泄密风险&#xff0c;同时还需要对文档内容本身进行有效的保护。为了防范通过拷贝、截屏、拍照等手段盗窃重要文档内容信息的风险&#xff0c;迅软DSE加密软件提供了文档加密保护功能&#xff0c;能…

10 新字符设备驱动文件

一、新字符设备驱动原理 因为 register_chrdev 和 unregister_chrdev 两个函数是老版本驱动文件&#xff0c;现在可以用新字符设备驱动 API 函数。 1. 分配和和释放设备号 使用 register_chrdev 函数注册字符设备的时候只需要给定一个主设备号即可&#xff0c;但是这样会带来两…

如何计算2的n次方

今天在写代码的时候&#xff0c;遇到了纹饰评分的计算&#xff0c;纹饰的等级和评分的关系为&#xff1a; 1级纹饰&#xff1a;202级纹饰&#xff1a;403级纹饰&#xff1a;80 得出纹饰等级grade和纹饰评分score的关系&#xff1a;score (2 ^ grade) * 10&#xff0c;所以就…

git 不小心操作 reset current branch to here后,怎么还原

可以通过reflog来进行恢复&#xff0c;前提是丢失的分支或commit信息没有被git gc清除 一般情况下&#xff0c;gc对那些无用的object会保留很长时间后才清除的 可以使用git reflog show或git log -g命令来看到所有的操作日志 恢复的过程很简单&#xff1a; 通过git log -g命…

信息安全和网络安全的区别

信息安全与网络安全都属于安全领域&#xff0c;但它们的范围和重点不同。 信息安全主要关注数据的保护&#xff0c;包括对敏感数据进行加密、防止数据丢失或泄露等措施。信息安全通常与数据存储、传输和处理相关。 而网络安全更侧重于保护计算机系统和网络免受攻击、病毒、蠕…

Mac安装软件显示文件已损坏处理方法

今天安装软件&#xff0c;突然遇到了文件已损坏&#xff0c;扔到废纸篓的情况&#xff0c;于是搜索了下解决办法&#xff0c;跟大家分享下&#xff0c;希望对你有所帮助 一、检查安全性设置 打开【设置】-【隐私与安全】&#xff0c;下拉找到安全性&#xff0c;将安全性更改为…

自定义指令Custom Directives

<script setup langts> import { ref } from "vue"const state ref(false)/*** Implement the custom directive* Make sure the input element focuses/blurs when the state is toggled* */ // 以v开头的驼峰式命名的变量都可以作为一个自定义指令 const VF…

System作为系统进程陔如何关闭?

一、简介 system进程是不可以关闭的&#xff0c;它是用来运行一些系统命令的&#xff0c;比如reboot、shutdown等&#xff0c;以及用来运行一些后台程序&#xff0c;比如ntfs-3g、v4l2loopback等。system进程也被用于运行一些内核模块&#xff0c;比如nvidia、atd等。system进程…