cf 库

cf库是框架封装给开发者使用的事件驱动库.

API使用方法

使用之前需要先导入cf库. 导入方式为: local cf = require "cf".

cf.fork(function)

调用此方法将会创建一个由cf管理的协程, 协程会自行启动/结束/回收.(目前不支持手动停止并销毁). 此方法没有返回值.

示例:

  1. cf.fork(function()
  2. -- do something
  3. end)

注意! 此方法不会阻止当前协程继续执行下去.

cf.self()

调用此方法将会返回当前上下文的协程对象, 其行为等同于调用coroutine.running方法.

使用示例:

  1. local co, is_main = cf.self()

cf.wait()

调用此方法将会暂停并且让出当前协程的执行权. 此方法的返回值可以由wakeup进行传递.

使用示例:

  1. local a = 1
  2. local b = 2
  3. local co = cf.self()
  4. cf.fokr(function ()
  5. return cf.wakeup(co, a + b)
  6. end)
  7. local result = cf.wait()
  8. print(result)

cf.wakeup(co, …)

调用此方法将会唤醒co协程并让他继续执行, 试图唤醒一个不存在的协程或正在运行的协程将会出现异常. co之后的参数将会传递给wait方法调用处.

注意! 此方法不会阻止当前协程继续执行下去.

使用示例:

  1. local co = cf.self()
  2. cf.fork(function ()
  3. return cf.wakeup(co, 1, 2, 3)
  4. end)
  5. local ret1, ret2, ret3 = cf.wait()
  6. print(ret1, ret2, ret3)

cf.sleep(time)

调用此方法将会阻塞当前协程time秒后才继续执行, time为不同参数的时候行为不同:

  • 当时间参数大于0的时候, 当前协程会暂停指定的时间且让出执行权. 当指定的时间超时后函数将会返回继续执行下面的代码.

  • 当时间参数等于0的时候, 当前协程会暂停并且让出执行权. 当其它协程执行完毕(让出)后立刻返回.

  • 当时间参数小于0或者非number类型的时候, 此方法将立刻返回.

使用示例:

  1. cf.fork(function ()
  2. print("休眠期间我执行了1次")
  3. end)
  4. print("休眠第1次, 时间为1秒")
  5. cf.sleep(1)
  6. print("休眠第2次, 时间为2秒")
  7. cf.sleep(2)
  8. print("休眠第3次, 时间为3秒")
  9. cf.sleep(3)
  10. print("运行完毕")

cf.at(time, func)

调用此方法将会创建一个循环定时器并且每time秒执行一次func函数, 返回值为此定时器的timer对象.

这个函数将会一直执行下去, 直到开发者主动调用timer:stop方法.

此方法不会阻止当前协程继续执行下去.

使用示例:

  1. local timer
  2. timer = cf.at(1, function ()
  3. print("定时器正在运行")
  4. end)
  5.  
  6. -- 取消下面的注释, 定时器将不会执行
  7. -- timer:stop()

cf.timeout(time, func)

调用此方法将会创建一个一次性定时器, 当time秒后将会执行一次func函数. 返回值为此定时器的timer对象.

这个函数将会在运行完成之后由框架主动停止, 当然开发者也可以主动调用timer:stop方法停止定时器.

此方法不会阻止当前协程继续执行下去.

使用示例:

  1. local timer
  2. timer = cf.timeout(1, function ()
  3. print("定时器正在运行")
  4. end)
  5.  
  6. -- 取消下面的注释, 定时器将不会执行
  7. -- timer:stop()

关于cf封装的使用注意事项

cf是基于一些列内置的底层API封装完成的异步库, 在对底层实现不够了解的情况下务必不要随便跨层级调用底层API.

cf底层定时器是基于最小堆(最小四叉堆)实现的, 在不使用海量高精度定时器的场景下不会有性能问题.

cf底层的协程实现是由事件驱动内部自行调度. 所以开发者不能假设哪个协程先、后运行, 并且最好也不要做这样的假设.

cf底层的协程调度生命周期管理由框架负责. 用户无需在创建之后进行手动停止, 但是不要让协程一直循环往复的执行一个永远不可能完成的任务.