之前对skynet的印象,主要是来自于我对golang的理解,对gevent开发的经验,以及云风的blog。对于底层的代码,并没有仔细去阅读过。最近在实现业务系统的时候,发现有同事在同一个函数里做了一个互斥的判断,才发现对skynet的理解有误。

以前,用python的gevent框架实现游戏服务器的时候,会针对每个玩家建立3-5个greenlet(协程),用于处理玩家身上的定时器事件,以及IO操作。然后还有少数几个协程处理全局的定时器事件。当然,战斗是放在独立的进程中实现的,那边基本上每个怪都有1-2个greenlet,一个房间里有几十个greenlet是很正常的。总结起来,就是python+gevent为了规避全局锁,采用了多进程,每个进程多greenlet的实现方式。

而对于golang,会变成底层是多线程模型,上面跑着多个goroutine,当一个goroutine发起阻塞式IO的时候,底层负责跑这个goroutine的线程,可以随之阻塞等待。系统便随即开一个新的线程,从一堆goroutine里挑一个可以执行的,继续执行。golang就相当于用多线程,取代了以前py的多进程。

读完云风的blog,我对skynet的理解,就是每个线程来跑一个Lua的VM,一系列的VM组成了一个队列。然后每个VM有自己的消息队列,VM运行时,就从自己的消息队列里,拿出一条消息执行。得益于Lua的沙盒机制,即使某个VM发生traceback,也能得到有效隔离。同时,因为同处一个进程内,VM之间数据交互可以做到相当高效,字符串之类的传递只要传指针即可。

但是,我之前忽略了Lua协程在其中发挥的作用。原来,一个服务(即一个VM)收到一个包req,就会新建一个协程进行处理。处理过程中,如果产生一个对外的call请求,req包是当成处理完的,当前的协程是会刮起,等待call请求返回来唤醒。这时候服务可以继续建立新的协程来处理新的消息包,而不会阻塞住。也就是说,如果处理一个包的过程中,发生了skynet.call调用,是会造成多个协程并发执行的。如果不注意用锁保护协程间的共享资源,就有可能出现问题。

skynet的协程的更多相关文章

  1. skynet源码阅读<5>--协程调度模型

    注:为方便理解,本文贴出的代码部分经过了缩减或展开,与实际skynet代码可能会有所出入.    作为一个skynet actor,在启动脚本被加载的过程中,总是要调用skynet.start和sky ...

  2. [转]skynet Lua中的协程

    Lua中的协程 http://www.outsky.org/code/lua-coroutine.html Sep 6, 2014 Lua中的协程和其他变量一样,都是第一类值(first-class ...

  3. Python(八)进程、线程、协程篇

    本章内容: 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 线程 Threading用于提供线程相关的操作.线程是应用 ...

  4. Lua的协程和协程库详解

    我们首先介绍一下什么是协程.然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复杂用法. 一.协程是什么? (1)线程 首先复习一下多线程.我们都知道线程——Thre ...

  5. 协程--gevent模块(单线程高并发)

    先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...

  6. Python 【第五章】:线程、进程和协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...

  7. 进击的Python【第十章】:Python的socket高级应用(多进程,协程与异步)

    Python的socket高级应用(多进程,协程与异步)

  8. unity 协程

    StartCoroutine在unity3d的帮助中叫做协程,意思就是启动一个辅助的线程. 在C#中直接有Thread这个线程,但是在unity中有些元素是不能操作的.这个时候可以使用协程来完成. 使 ...

  9. golang 裸写一个pool池控制协程的大小

    这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770& ...

随机推荐

  1. GZFramwork快速开发框架之窗体设计说明

    1.  明细页数据源获取(基类已经处理) 重载GetEditData方法,此方法为自定义获得明细也的数据源,用于绑定明细页,此返回值会赋值给EditData //根据主键获得数据编辑页的数据 publ ...

  2. 微信小程序文件作用域模块引用

    文件作用域 在 JavaScript 文件中声明的变量和函数只在该文件中有效:不同的文件中可以声明相同名字的变量和函数,不会互相影响. 通过全局函数 getApp() 可以获取全局的应用实例,如果需要 ...

  3. 激活、复制、使用R/3标准数据源(RSA5、RSA6、RSA1)

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  4. python_way ,day25 CMDB_models (数据库设计)

    from django.db import models from django.contrib.auth.models import User # Create your models here. ...

  5. (原创)Windows和Linux间共享文件

    方法一: Windows创建目录sharedir,修改共享属性,对everyone开放读写权限. Linux下运行命令:# mount -t cifs //192.168.8.55/sharedir ...

  6. HTTP中的摘要认证机制

    引子: 指定和服务器端交互的HTTP方法,URL地址,即其他请求信息: Method:表示http请求方法,一般使用"GET","POST". url:表示请求 ...

  7. (转)Uiautomator——API详解

    原文链接:http://www.cnblogs.com/by-dream/p/4921701.html#3328376 以一个简单的例子开始吧.我们完成一个 " 打开QQ,进入QQ空间,然后 ...

  8. Oracle的表空间和数据文件

    一. 概念 表空间:是一个或多个数据文件的逻辑集合 表空间逻辑存储对象: 永久段-->如表与索引 临时段-->如临时表数据与排序段 回滚段-->用于事物回滚或闪回内存的撤销数据 表空 ...

  9. Oracle的不完全恢复

    一.不完全恢复特性 1.不完全恢复 不完全恢复仅仅是将数据恢复到某一个特定的时间点或特定的SCN,而不是当前时间点.不完全恢复会影响整个数据库,需要在MOUNT状  态下进行.在不完全恢复成功之后,通 ...

  10. Android SharePreference 在主进程和次进程间共享数据不同步出错

      SharedPreference作为android五大存储(网络,数据库,文件,SharedPreference,contentProvider)之中最方便使用的一个,从类名上来看就不是一个存储大 ...