一、前言
在之前的文章中我们讲到了 go
并发编程会导致非线程安全问题,在多个协程内同时对一个切片写入会造成数据丢失问题,具体翻查上篇文章
二、swoole是否会产生线程安全问题?
先看一段代码,想想你心中的答案:
1 | $wg = new WaitGroup(); |
看上去是不是和 go
很像?没错感觉是有点借鉴的成分哈,你们猜猜这里会不会和 go
一样,并发对一个数组的指针地址中塞东西,产生内存地址抢占,导致数据丢失呢?
答案是:不会的,结果如图
为什么呢?同样是”并发读写”,为什么我要加个双引号呢?具体我们看看 swoole
的协程和 go
的协程区别哈,有一篇文章讲的特别细致,大家可以看看:Swoole协程与Go协程的区别,很详细,很牛逼
总结来说就是:
- Swoole协程:基于单线程的, 无法利用多核CPU,同一时间只有一个在调度。
- Go协程:基于多线程的,可以利用多核 CPU,同一时间可能会有多个协程在执行。
所以说,其实可以理解为 swoole协程
并非真的”并发读写”,同一时间只有一个协程在调度的意思其实就是并非多线程的,而是一个单线程在执行,其他的协程会在IO等待,这样其实还是有序的向数组的指针地址存数据了,不会造成争抢。 而 Go协程
是天生就支持的,支持同一时间多个协程在调度,才会导致非线程安全问题。
三、结语
如果还不清除,我用一张图表示一下swoole的协程:
也就是就算电脑有100个核心,swoole
在协程调度的时候,还是只能用一个核心去干这件事情,虽然这样看上去并不太美好,但是 swoole
给 php
确实带来了又一春,让 php
又有了更多的可能~