• 欢迎来到我的博客
  • [email protected]

Go 协程 和 Swoole 协程

学习笔记 tianlan 1年前 (2020-04-07) 503次浏览 0个评论 扫描二维码
文章目录[隐藏]

Go 协程原理

Go 语言运行时会在底层通过调度器将用户级线程交给操作系统的系统级线程去处理如果在运行过程中遇到某个 IO 操作而暂停运行,调度器会将用户级线程和系统级线程分离,以便让系统级线程去处理其他用户级线程,而当 IO 操作完成,需要恢复运行,调度器又会调度空闲的系统级线程来处理这个用户级线程,从而达到并发处理多个协程的目的。此外,调度器还会在系统级线程不够用时向操作系统申请创建新的系统级线程,而在系统级线程过多的情况下销毁一些空闲的线程,这个过程和 PHP-FPM 的工作机制有点类似,实际上这也是很多进程/线程池管理器的工作机制,这样一来,可以保证对系统资源的高效利用,避免系统资源的浪费。

Swoole 协程

Swoole4Go协程在设计上是完全一致的,均是stackful的,每个协程拥有独立的运行栈。协程调度器使用汇编代码,切换协程上下文。

区别

  • Swoole4的协程调度器是单线程的,因此不存在数据同步问题,同一时间只会有一个协程在运行
  • Go协程调度器是多线程的,同一时间可能会有多个协程同时执行

因此在Swoole4协程中操作全局变量是不需要加锁的。而Go的程序由于依然是类似Java的多线程模式,因此务必要对临界资源加锁,避免出现数据同步问题。或者使用官方sync包提供的各种并发容器。

实际上Gochan和并发容器,底层仍然使用了Mutex进行锁操作,锁的争抢是普遍存在的。

Swoole4由于是单线程多进程的,底层没有使用任何Mutex锁,不存在锁的争抢。 同样带来的问题是,没有超全局变量。只有进程级全局变量,读写PHP全局变量只在当前进程内有效。如果希望多进程共享数据,有3种解决方案:

  • 使用TableAtomic对象,或者其他共享内存数据结构
  • 使用IPC进程间通信
  • 借助存储共享数据和中转,如RedisMySQL文件操作

Go 协程 和 Swoole 协程

 

参考

https://wiki.swoole.com/wiki/version/?id=1018&version=2

Go 协程 和 Swoole 协程


天蓝, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Go 协程 和 Swoole 协程
喜欢 (0)
[[email protected]]
分享 (0)

您必须 登录 才能发表评论!