一直让 PHP 程序员懵逼的同步阻塞异步非阻塞,终于搞明白了

源码技巧4个月前 (09-30)40232544

经常听到身边写 Java、Go 的朋友提到程序异步、非阻塞、线程、协程,让系统性能提高到百万、千万并发,使我甚是惊讶属实羡慕。对于常年写 PHP 的我来说,最初听到这几个词时,脑袋一直处于蒙圈状态,回过头来看着自己手上同步阻塞的 PHP 代码,心想着「异步、非阻塞、线程、协程」到底是个什么东东,这么厉害嘛。其实 PHP 中也有线程、协程,但在日常的编程中几乎不会使用,原因是 PHP-FPM 多进程模式下并不支持线程、协程,使用 PHP 编程的程序员绝大多数都离不开 PHP-FPM 。这也就导致了 PHP 程序员对那些概念没有接触,那就更别提理解了,因此为了广大的 PHP 程序员同胞们能够和 Java、Go 的程序员对上话,特地对「同步、阻塞、异步、非阻塞」这几个概念进行了深度的分析,争取把 PHP 程序员的腰杆挺直溜。

按照惯例先上八股文这道菜:

  • 同步阻塞:当一个操作被调用时,调用者将被阻塞,直到这个操作完成并返回结果。在此期间,调用者无法进行其他任务。

  • 异步阻塞:当一个操作被调用时,调用者不会被阻塞,而是可以继续执行其他任务。然而,它仍然需要等待被调用的操作完成,并在操作完成后处理其结果。这个等待过程可能是阻塞的。

  • 同步非阻塞:调用者发起一个操作后,不会被阻塞并可以继续执行其他任务。虽然调用者可以立即获得控制权,但它仍然需要等待操作完成才能处理结果。在等待的过程中,调用者可以主动轮询或者不断尝试获取操作结果,以避免长时间的阻塞。

  • 异步非阻塞:调用者发起一个操作后,不会被阻塞并可以继续执行其他任务。同时,调用者也不需要等待操作完成来处理结果。相反,调用者可以注册一个回调函数或者使用类似事件驱动的机制,当操作完成后被自动触发回调函数来处理结果。

基础知识扎实的朋友看这个八股文就足以解惑了,不过看得懂八股文的毕竟是少数英俊帅气人,你说气不气人集颜值与才华于一体,别看说的就是各位看官「哈哈」。言归正传,那看不懂八股文的怎么搞?别急,且听我结合生活中的例子娓娓道来。

你每天上班匆匆路过的早餐店,今天额外的多人,你凑近一看原来是来了位身材高挑楚楚动人的美女服务员,结果你按耐不住心中的激动,今天高低得买两个馒头外加一杯豆浆,由于买的人太多,蒸好的馒头早已卖完,这时你只能等正在蒸的,期间你什么也干不了只能眼勾勾的干等着,那么这时的你是同步阻塞的。

由于来买早餐的人越来越多,离上班的时间也越来越近,你开始了骚动,每隔几分钟就问美女服务员馒头蒸好了没?此时的你不再干等,而是开始刷刷抖音看看工作群,因为你已经付钱了所以还是得等馒头,由于美女服务员太忙了没空主动告诉你,需要你自己不断地问,那么这时的你是同步非阻塞的。

过了高峰期人变少了,视野更广阔了,你看美女服务员更清楚了,结果你又开始眼勾勾的干等着,抖音也不刷了工作群的消息也不顾了。由于美女服务员不忙了,开始主动叫那位身穿格子衫背双肩包帅哥,馒头蒸好了,这时的你甩了甩头上的刘海,接过了美女服务员手中的馒头会心一笑,顺便还加了对方的微信,那么此时的你是异步阻塞的。

隔天你为了再睹芳容,又来到了这家早餐店,一向抠门的你甩手就点了两个肉包。这时美女服务员迎面笑脸告知你肉包还需耐心等待哦,蒸好了会微信通知你。在炎炎的夏日里你路上走的太匆忙,此时的你口渴难耐,就去隔壁小卖部买了瓶82年的可乐,还坐着吹了会空调。随着微信的一声叮咚,你起身去早餐店,接过了美女服务员手中的肉包,那么此时的你是异步非阻塞的。

有了美女服务员的投喂,你工作的干劲都十足了,同时应该也把「同步、阻塞、异步、非阻塞」这几个概念搞懂了吧。其实这里的同步异步和阻塞非阻塞,容易搞混淆就像你看美女服务员容易丢魂一样,在这个例子中同步异步需要关注的是「美女服务员是否会主动的通知你」,主动通知你那么对你来说就是异步的,需要你去询问那么对你来说就是同步的。阻塞非阻塞需要关注的点是「你是否是眼勾勾的干等着」,如果你只能干等那就是阻塞的,如果你还能干点其他的事情比如刷抖音、买82年的可乐,那么就是非阻塞的。

美女也看了道理也懂了,有的朋友们又要产生新的疑问了,那在程序中怎么体现、怎么用「同步、阻塞、异步、非阻塞」呢?那我们就开始上代码,毕竟看美女服务员的目的也是为了能够深入交往嘛,也就等同于实践上手了,你细品是不是这个理。

开整!

我们先来看同步阻塞的例子,使用 socket_create、socket_bind、socket_listen 函数创建绑定并监听了 8080 端口,然后一直阻塞在 socket_accept 函数上,直到有客户端连接的到来。传统的 PHP-FPM 就是同步阻塞的模式,不过 PHP-FPM 多进程模型,在接收到客户端连接 $client 后就交给由子进程进行后续的处理了,在这个例子只举例了单进程的模式。

Copy<?php// 同步阻塞模式// 创建一个监听 Socket$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);// 绑定 8080 端口socket_bind($socket, '0.0.0.0', 8080);// 开始监听socket_listen($socket);while(true){    // 会阻塞在这里,一直等着客户端来连接
    // 结合刚刚的例子可以理解为,你一直在这里眼勾勾的干等馒头,啥也干不了
    $client = socket_accept($socket);    if($client){        echo "客官来了" . PHP_EOL;
    }
}

再来看看同步非阻塞的例子,同样也是监听了 8080 端口,不同的是将套接字 $socket 设置成了非阻塞模式。那么这种情况下将不会一直阻塞在 socket_accept 函数上,会继续往下执行,如果没有写其他的逻辑,就会出现放空炮的现象。这种模式在实际的编程中基本上不会采用,会把系统榨干,这一点值得注意一下,谁写了这样的代码就要拉出去罚站了。

Copy<?php// 同步非阻塞模式// 创建一个监听 Socket$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);// 绑定 8080 端口socket_bind($socket, '0.0.0.0', 8080);// 开始监听socket_listen($socket);// 这里设置成非阻塞socket_set_nonblock($socket);while(true){    // 不会阻塞在这里
    $client = socket_accept($socket);    if($client){        echo "客官来了" . PHP_EOL;
    }    // 会继续往下执行
    // 结合刚刚的例子,可以在这里刷刷抖音、看看工作群消息等
    // ...

    // 如果你上面没有写任何的逻辑,这些最好 sleep 一下
    // 不然 CPU 就会被榨干了,也就是说不要一直眼勾勾的盯着美女服务员会被吸干
    // 要适当的休息一下
    sleep(5);
}

继续接着看看异步阻塞的例子,还好有 Swoole 不然这种模式的例子都没有地方找了,这里感谢一下 Swoole 为 PHP 程序员做的贡献,让我们硬气了一回。构造一个 HTTP 服务并监听了 9501 端口,然后设置了针对 Request 的异步回调函数,但如果在回调函数里面使用了类似 sleep、PDO 等的 PHP 原生函数,就会阻塞整个进程,导致无法处理其他的 Requset 请求。这种情况下的程序性能直接和同步阻塞等同了,所以异步阻塞模式在实际的编程实践中也不常用,还不如使用同步阻塞模式了。这里提醒一点,在新版的 Swoole 中已经可以通过 HOOK 的方式支持 PHP 原生函数协程化了,这一点也值得庆幸。

Copy<?php// 异步阻塞模式// 创建一个 Swoole 的异步 HTTP 服务器$http = new Swoole\Http\Server('127.0.0.1', 9501);// 设置异步回调函数$http->on('request', function ($request, $response) {    // 阻塞了整个进程,使用 PHP 原生的 PDO、Redis 等都会阻塞当前进程
    // 结合刚刚的例子,只能干等着,这里你啥也干不了
    sleep(5);    $response->end("OK");
});// 启动服务器$http->start();

最后来看看异步非阻塞的例子,这种模式是目前在实践中性能最好的,和上面例子唯一不同的是在 Request 回调函数中使用了协程类,便不会阻塞整个进程,能够释放出 CPU 的控制权去处理其他的请求。当然在新版的 Swoole 中也不一定需要使用协程类,使用原生的函数同样不会阻塞进程了,这一点大大减低了 PHP 程序员编程的心智负担。

Copy<?php// 异步非阻塞模式// 创建一个 Swoole 的异步 HTTP 服务器$http = new Swoole\Http\Server('127.0.0.1', 9501);// 设置异步回调函数$http->on('request', function ($request, $response) {    // 不会阻塞整个进程,这里还可以使用类似其他的协程客户端
    // swoole\Coroutine\MySQL
    // swoole\Coroutine\Redis
    // 结合刚刚的例子,这里你可以去刷抖音、买82年的可乐
    // 也是说你有空去处理其他的请求了,不用这里干等
    // 等5秒过后,又可以回来继续向下执行,接过肉包之后你就可以上班去了,虽然你有百般不舍。
    Co::sleep(5);    $response->end("OK");
});// 启动服务器$http->start();

虽然你依然忘不了早餐店美女服务员的容颜,但空空的口袋催促着你赶紧去上班了。看到这里你既欣赏了美女的容颜,同时又把「同步、阻塞、异步、非阻塞」也搞懂了,简直两全其美,了解了这些概念对以后学习 Go 语言也大有裨益。但是大家都知道这么一个道理,看懂了并不等于真的懂了,很多人一看就会一做就废,因此最好自己上手实践一下,在知中行,在行中知,做到知行合一,就像看美女服务员不是目的而是想要更深入一步交流,就此打住哈哈。在市面上绝大多数的高性能程序都是异步非阻塞的模式,比如 Nginx、Redis 等,如果大家想写出高性能的程序最好是优先考虑这种模式,因为借鉴才是最快的学习方法。本次分享的内容到就此结束了,希望对大家能有所帮助。


标签: php阻塞

“ 一直让 PHP 程序员懵逼的同步阻塞异步非阻塞,终于搞明白了 ” 的相关文章

评论列表

telegram电脑版
4个月前 (09-30)

楼主很有艺术范!http://2gtg.https://www.telegramis.com/

telegram中文电脑官方网站

楼主是男的还是女的?http://wp0pa.https://www.telegramlp.com/

telegram电脑版网站
4个月前 (09-30)

态度决定一切,不错!http://2pahyq.https://www.telegramlp.com/

skype电脑版
4个月前 (10-01)

态度决定一切,不错!http://75d9f.https://www.skypeis.com/

telegram网站
4个月前 (10-01)

在这个版块混了这么久了,第一次看见这么给你的帖子!http://h5eu.https://www.telegramlp.com/

telegram中文版网站
4个月前 (10-01)

没人理我,好伤心啊!http://o67dy.https://www.telegramis.com/

skype官网
4个月前 (10-01)

鸟大了,什么林子都敢进啊!http://kc6fu.https://www.skypeis.com/

telegram中文版
4个月前 (10-01)

顶一下,收藏了!http://sso4g.https://www.telegramis.com/

telegram中文电脑官网
4个月前 (10-01)

观点鲜明,立场坚定,作者态度明确。http://x3ft.https://www.telegramis.com/

skype电脑版
4个月前 (10-01)

看了这么多帖子,第一次看看到这么有内涵的!http://wgr4dh.https://www.skypeis.com/

skype电脑版官方网站
4个月前 (10-01)

很给力!http://271f.https://www.skypeis.com/

telegram中文电脑版
4个月前 (10-01)

哥回复的不是帖子,是寂寞!http://jy6u6d.https://www.telegramlp.com/

skype电脑版网站
4个月前 (10-01)

楼主主机很热情啊!http://1a7e.https://www.skypeis.com/

skype电脑版官网
4个月前 (10-01)

楼主是一个典型的文艺青年啊!http://utiy.https://www.skypeis.com/

skype电脑版
4个月前 (10-01)

文章论点明确,论据充分,说服力强。http://oo6uq0.https://www.skypeis.com/

telegram中文电脑版
4个月前 (10-01)

赞一个!http://frqomj.https://www.telegramis.com/

telegram中文官方网站
4个月前 (10-01)

看帖、回帖、拿分、走人http://30yt.https://www.telegramlp.com/

telegram中文电脑官网
4个月前 (10-01)

谢谢楼主的分享!http://r4m4w.https://www.telegramlp.com/

skype官网
4个月前 (10-01)

这一年啥事没干,光研究楼主的帖子了!http://zoddbb.https://www.skypeis.com/

skype电脑版
3个月前 (10-01)

这么好的帖子,应该加精华!http://z56.https://www.skypeis.com/

telegram中文网站
3个月前 (10-01)

看帖回帖一条路!http://a36m.https://www.telegramlp.com/

skype电脑版官网
3个月前 (10-01)

知识就是力量啊!http://ekap7.https://www.skypeis.com/

telegram电脑版官方网站
3个月前 (10-01)

读了楼主的帖子,顿时马桶就通了。。。http://3t4t39.https://www.telegramis.com/

skype官网
3个月前 (10-02)

好无聊啊!http://65n.https://www.skypeis.com/

telegram中文电脑官网
3个月前 (10-02)

经典,收藏了!http://j97yr.https://www.telegramis.com/

skype电脑版官网
3个月前 (10-02)

白富美?高富帅?http://mig.https://www.skypeis.com/

telegram电脑版官方网站
3个月前 (10-02)

顶一个!http://9q8q1.https://www.telegramlp.com/

skype官网
3个月前 (10-02)

楼主该去看心理医生了!http://xkm.https://www.skypeis.com/

telegram中文版官方网站
3个月前 (10-02)

坚持回帖!http://dfh.https://www.telegramlp.com/

skype电脑版官方网站
3个月前 (10-02)

缺乏激情了!http://s0y69a.https://www.skypeis.com/

skype官网
3个月前 (10-02)

我回帖楼主给加积分吗?http://g2qesd.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-02)

楼主是好人!http://49lhi4.https://www.skypeis.com/

telegram中文官网
3个月前 (10-02)

楼主你想太多了!http://apd.https://www.telegramis.com/

telegram中文版网站
3个月前 (10-02)

经典!http://0fa.https://www.telegramlp.com/

skype电脑版网站
3个月前 (10-02)

很有品味!http://4o7m.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-02)

楼主练了葵花宝典吧?http://4vu2b.https://www.skypeis.com/

skype电脑版网站
3个月前 (10-02)

刚分手,心情不好!http://oihz.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-02)

坚持回帖!http://aq8.https://www.skypeis.com/

telegram电脑版官网
3个月前 (10-02)

楼主该去看心理医生了!http://s3adcs.https://www.telegramis.com/

skype电脑版官网
3个月前 (10-03)

太邪乎了吧?http://44b.https://www.skypeis.com/

telegram中文官方网站
3个月前 (10-03)

好东西,赞一个!http://idhnw.https://www.telegramlp.com/

skype电脑版官网
3个月前 (10-03)

楼上的真不讲道理!http://kv8wu.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-03)

最近压力山大啊!http://6nrx.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-03)

信楼主,得永生!http://hwusu.https://www.skypeis.com/

skype电脑版网站
3个月前 (10-03)

观点鲜明,立场坚定,作者态度明确。http://y4t.https://www.skypeis.com/

skype官网
3个月前 (10-03)

态度决定一切,不错!http://pf9xz.https://www.skypeis.com/

skype电脑版
3个月前 (10-03)

经典!http://n3nf.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-03)

有内涵!http://jf7f5.https://www.skypeis.com/

skype电脑版网站
3个月前 (10-03)

林子大了,什么鸟都有了啊!http://em2do.https://www.skypeis.com/

skype电脑版官网
3个月前 (10-03)

楼上的很有激情啊!http://4s3csq.https://www.skypeis.com/

skype电脑版网站
3个月前 (10-03)

哥回复的不是帖子,是寂寞!http://p8ix6.https://www.skypeis.com/

skype电脑版
3个月前 (10-03)

看了这么多帖子,第一次看到这么有深度了!http://es5.https://www.skypeis.com/

skype电脑版网站
3个月前 (10-03)

一口气看完了,我要下去回味回味了!http://vh578.https://www.skypeis.com/

telegram中文电脑版官网
3个月前 (10-04)

楼主的帖子实在是写得太好了。文笔流畅,修辞得体!https://www.telegramlp.com/

telegram中文官网
3个月前 (10-04)

世界末日我都挺过去了,看到楼主我才知道为什么上帝留我到现在!https://www.telegramlp.com/

skype电脑版官方网站
3个月前 (10-04)

有钱、有房、有车,人人都想!https://www.skypeis.com/

telegram电脑官方网站
3个月前 (10-04)

这么好的帖子,应该加精华!https://www.telegramlp.com/

skype电脑版
3个月前 (10-04)

宇宙第一贴诞生了!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-04)

不是惊喜,是惊吓!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-04)

楼上的心情不错啊!https://www.skypeis.com/

skype电脑版
3个月前 (10-04)

大神好强大!https://www.skypeis.com/

skype电脑版
3个月前 (10-04)

学习雷锋,好好回帖!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-04)

楼上的很有激情啊!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-05)

楼主内心很强大!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-05)

小弟默默的路过贵宝地~~~https://www.skypeis.com/

skype电脑版
3个月前 (10-05)

这个帖子好无聊啊!https://www.skypeis.com/

skype电脑版
3个月前 (10-05)

楼主发几张靓照啊!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-05)

楼主的头像能辟邪啊!https://www.skypeis.com/

skype官网
3个月前 (10-05)

经典!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-05)

刚分手,心情不好!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-05)

顶一下,收藏了!https://www.skypeis.com/

skype电脑版官网
3个月前 (10-05)

每次看到楼主的帖子都有惊吓!https://www.skypeis.com/

skype电脑版
3个月前 (10-06)

今天怎么了,什么人都出来了!https://www.skypeis.com/

skype电脑版
3个月前 (10-06)

很有品味!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-06)

楼主最近很消极啊!https://www.skypeis.com/

skype电脑版
3个月前 (10-06)

看了这么多帖子,第一次看到这么有深度了!https://www.skypeis.com/

skype电脑版
3个月前 (10-06)

楼主发几张靓照啊!https://www.skypeis.com/

telegram中文电脑版
3个月前 (10-06)

刚看见一个妹子,很漂亮!https://www.telegramis.com/

skype电脑版官网
3个月前 (10-06)

大神好强大!https://www.skypeis.com/

skype电脑版网站
3个月前 (10-06)

楼主很有经验啊!https://www.skypeis.com/

skype电脑版
3个月前 (10-06)

楼主很有激情啊!https://www.skypeis.com/

skype电脑版网站
3个月前 (10-06)

终于看完了,很不错!https://www.skypeis.com/

telegram中文电脑版网站
3个月前 (10-07)

感谢楼主的推荐!https://www.telegramlp.com/

skype电脑版官方网站
3个月前 (10-07)

论坛人气好旺!https://www.skypeis.com/

skype官网
3个月前 (10-07)

楼主很有激情啊!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-07)

楼主英明!https://www.skypeis.com/

telegram电脑版官方网站
3个月前 (10-07)

怪事年年有,今年特别多!https://www.telegramis.com/

skype官网
3个月前 (10-07)

我就搞不明白了,看帖回帖能死人么,居然只有我这么认真的在回帖!https://www.skypeis.com/

telegram电脑官方网站
3个月前 (10-07)

帖子好乱!https://www.telegramis.com/

skype电脑版
3个月前 (10-07)

世界末日我都挺过去了,看到楼主我才知道为什么上帝留我到现在!https://www.skypeis.com/

skype官网
3个月前 (10-07)

我对楼主的敬仰犹如滔滔江水绵延不绝!https://www.skypeis.com/

skype电脑版官方网站
3个月前 (10-07)

今天过得很不爽!https://www.skypeis.com/

telegram中文电脑版
3个月前 (10-07)

赞一个!https://www.telegramis.com/

skype电脑版官网
3个月前 (10-07)

支持一下,下面的保持队形!https://www.skypeis.com/

skype电脑版
3个月前 (10-07)

读了楼主的帖子,顿时马桶就通了。。。https://www.skypeis.com/

telegram中文电脑官网
3个月前 (10-07)

楼主是一个神奇的青年!https://www.telegramlp.com/

skype官网
3个月前 (10-07)

好帖子!https://www.skypeis.com/

skype电脑版
3个月前 (10-07)

经典!https://www.skypeis.com/

telegram中文电脑网站
3个月前 (10-07)

楼主加油,看好你哦!https://www.telegramis.com/

telegram中文版
3个月前 (10-07)

林子大了,什么鸟都有了啊!https://www.telegramlp.com/

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。