V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 10 页 / 共 53 页
回复总数  1055
1 ... 6  7  8  9  10  11  12  13  14  15 ... 53  
@rockyliang #96

汇编在这里,去掉了 fmt 换成了 println 免得太长影响视线:
https://gist.github.com/lesismal/3673322106d032abc10a2a06ee138f9b
@rockyliang #96

看了下汇编,for 循环里不断设置 flag 的语句这块生成的汇编只有一条 NOPL (空指令)汇编、应该是被编译器优化掉了。
随便在 for 循环里加个 print 之类的,都可以让 flag=false 生效。

OP 的疑问其实是 CPU 指令自己的事情,并不算是编程语言相关的,所以我再提一下这个帖子,建议 OP 先看下:
https://www.51cto.com/article/716546.html
还有例如这个帖子:
https://xiaolincoding.com/os/1_hardware/cpu_mesi.html#mesi-%E5%8D%8F%E8%AE%AE

CPU 多核缓存一致性由 CPU 保证。一些人举例子的 i++是属于多个并发各自执行一组指令时各组指令自己的原子性问题、和 cache 一致性其实应该是无关的。

很多认为的可见性的不一致问题,应该是编译器优化导致的,例如:
#96
c++ const 变量通过指针强改内容但其他用到 const 变量的地方仍然是旧值、因为编译器认为常量直接类似宏替换了,需要 volatile 指定每次读内存主要也是为了告诉编译器不要优化这里的内容
@rockyliang
如果只是并行 cpu cache 的问题,相当于跟 golang 语言无关、跟 chan 也无关,直接看这种吧:
https://www.51cto.com/article/716546.html

@Frankcox #68 嗯嗯
135 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@guanhui07 除了 #82 里说的,其他还有很多,go 并发编程里随便弄些协程做常驻任务运行,还可以方便结合 chan 、mutex 之类的实现各种功能,我搜的 swoole 例子里主要是 http handler 处理 http 请求这种,更广泛的业务场景怕是差距更大,不只是简单的无状态接口这个地方的协程的便利性
@Frankcox #56

我也没有说是协程执行先后顺序的问题呀。。
可能我给那几个步骤排序,造成了你的误解、误以为我在说协程执行的先后顺序。
请仔细看下,我说的是不同协程里,golang 对 chan 的操作时序保证,这与 go f()是否被先调度执行是无关的

> OP 的疑问是如何确保如果两个协程在不同的 core 上执行,修改的值在不同的 core cache 上同步

不管你是单核心并发、还是多核心并发或并行,chan 都在语言层面通过锁、调度器做了这个对并发操作 chan 行为的顺序保证,就是官网里这句:A receive from an unbuffered channel is synchronized before the completion of the corresponding send on that channel.

所以 OP 把问题本身就搞混了
官网里这个例子前面那句写的很清楚了:
> A receive from an unbuffered channel is synchronized before the completion of the corresponding send on that channel.
> 无缓冲的 chan 的接收在该 chan 上相应的发送完成之前进行同步。

如果没有这个保证,c <- 0 可能先于 f()协程完成、所以很可能 a 还没被设置。
但有了这个保证,则例子中:
<-c 先于 c <- 0 完成;
a = "hello, world" 先于 <-c ,所以也先于 c <- 0;
print(a) 在 c <- 0 之后,所以 a = "hello, world" 先于 print(a),所以肯定打印了 hello world 。


本质上 OP 是迷惑为什么“无缓冲的 chan 的接收在该 chan 上相应的发送完成之前进行同步”。
这个可以自己啃下 runtime/chan.go 源码
完全没毛病,人家出钱了啊
135 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@guanhui07 #81

看了下,看样子 swoole 确实是框架内置了一些驱动已经与协程结合起来了,例如 mysql 、redis ,确实很不错。
但这毕竟仍然是框架级的,也就是说,必须得 swoole 框架支持慢 IO 操作才能真正实现同步代码底层非阻塞+自动调度。三方的东西很多,如果需要依赖一些 swoole 尚未支持的,则仍然是可能阻塞的。
golang 是语言级支持了这些,三方的 golang 驱动实现基于 golang 标准库即可获得同步代码底层非阻塞+自动调度。

所以也不能完全说“没什么不同”
136 天前
回复了 ysicing 创建的主题 美酒与美食 大家口粮茶都有啥,最近想换换口味
艺福堂口粮龙井,滇红经典 58
136 天前
回复了 dandankele 创建的主题 数据库 同 database 不同 schema 多租户连接池问题
看 OP 的需求应该是想 database 隔离、但是怕连接池数量太大吧,如果是这样、好像可以用同一组连接池,语句里指定 database 更好些吧,比如 select * from database.table ,但可能已有代码要改动很多
136 天前
回复了 lesismal 创建的主题 程序员 4C-2G 来战 [ Golang Websocket 百万连接测试 ]
@xbchaonba #33 好嘞!欢迎使用,如果有疑问、bug ,也欢迎来 issue 、PR
137 天前
回复了 lesismal 创建的主题 程序员 4C-2G 来战 [ Golang Websocket 百万连接测试 ]
@xbchaonba #30

> conn.SetReadDeadline(time.Now().Add(time.Second / 120)) 是要用这个方法更新吧

是用这个方法。
但你这个是 120 分之一秒,设置完后很快就过期了,如果没有立刻收到新消息,就 close 了

> 昨天试了好多次 u.KeepaliveTime = time.Second / 120 直接这样重新赋值没有用

同样的问题,估计也是因为 120 分之一秒太快了
137 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@shermie #75

还有一个问题,你说的这个 PHP 协程,不管需不需要 yield ,会不会在使用系统调用、其他慢 IO 时阻塞了,因为已有的很多系统调用、慢 IO ,比如网络 IO 、操作数据库,如果这些底层接口并没有自动出让线程,那跟我前面提到的 Java 虚拟线程可能会是类似的问题。当你处理这些的时候如果阻塞了、线程就在那等待了,不能充分利用 CPU 、不是协程那种真的并发。我只是猜测、我并不了解你说的这个 PHP 协程哈
138 天前
回复了 lesismal 创建的主题 程序员 4C-2G 来战 [ Golang Websocket 百万连接测试 ]
@xbchaonba #27

dev 修改了下,默认会开启读超时的更新,可以试下:
go get -u github.com/lesismal/nbio@a81e8e2

过阵子再发到新版
138 天前
回复了 GCP 创建的主题 程序员 🦽人体工学椅坐着腿疼,还不如电竞椅
@GCP #26

椅子这种还是得试坐,而且最好不只是简单试坐一会,至少模拟办公之类的坐上个把小时才好体验出来。否则八成都是人体不工学。
而且再怎么舒服、它也是久坐,解决不了根本问题,频繁起来走动、运动比任何椅子都强,而且可以治疗、康复颈肩腰痛。
139 天前
回复了 lesismal 创建的主题 程序员 4C-2G 来战 [ Golang Websocket 百万连接测试 ]
@xbchaonba #27

为了避免僵尸连接耗尽 server 资源,尤其是进电梯导致信号终断、移动信号切换信号塔、设备掉电等情况时,收不到 TCP 协议的 FIN ,连接一直无法退出。TCP 设置 keepalive 是检测四层链路健康,可以避免这种情况,但它并不能解决七层僵尸连接、慢连接的问题,因为四层链路可能一直是健康的,但这个连接什么数据都不发或者只发很少数据、仍然会耗尽 server 资源,所以七层的 keepalive 是需要的,有了七层、再做四层的 TCP 设置 keepalive 就画蛇添足了、没必要。既然应该做七层,所以就应该都设置读超时比较好,所以与其他很多框架默认不设置读超时不太一样,nbio 默认设置。

一直有发数据仍然断开是因为 Upgrade 过程中默认设置了 120s 读超时,但后续收到消息时没有自动更新读超时。
当前版本,server 端设置 upgrader.KeepaliveTime = YourKeepaliveDuration 即可自动更新读超时,设置 upgrader.KeepaliveTime = YourKeepaliveDuration 后,不只是 PING 、其他类型的 message 也都可以,因为是读到消息就更新超时。僵尸连接检测也不是必须要 PING 协议才行、有效的协议即可。
我考虑下,要不要把这个心跳间隔也做成默认配置、自动更新读超时。

如果不想设置读超时,可以在 Upgrade 后 SetReadDeadline(time.Time{}) 清空超时关闭。
燃风宁芝解君忧
139 天前
回复了 GCP 创建的主题 程序员 🦽人体工学椅坐着腿疼,还不如电竞椅
网易严选名字起得挺好,但产品真没见过几个好的

要么买米勒,要么必须现场多试几次并且最好坐多一会再确定。否则,95 成的人体工学椅,其实都是人体不工学
140 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@shermie #47

我搜了下,PHP 也有协程,所以我猜你是指 PHP 协程?
如果是这样,那我补充一点,除了 erlang 、golang ,多年前 lua 或者 c/cpp 也早就有协程或者库,但都是手动挡,比如 lua 的 yield resume ,我刚才搜的帖子里 PHP 的方式也是需要手动 yield 。
近几年 js py 之类的也搞了 async await 这些。确实,整体看上去是同步代码、顺序可读了。但是,这种手动挡理解起来并不直观,对于步骤层次不多的,个人觉得手动挡协程甚至不如 callback 。
nodejs 还有 Promise 这种,看上去是那个顺序,但并发的时序可能不是那个顺序,很多人因为这个写 bug 、或者理解吃力、或者要自己控制时序时非常麻烦。

很多人可能没有深度使用 erlang 、golang 协程,或者已经习惯了那些手动挡的蹩脚协程,所以 get 不到 erlang 、golang 这种像线程一样的并发有多爽。

Java 的虚拟线程还是啥也是类似协程,但似乎只是解决了语言指令级的调度,系统调用等行为并不会主动出让并可能因为阻塞占用了线程,我没有深入研究、不知道是否理解有误,但好像 Java 至少仍然需要解决大量的底层接口与虚拟线程调度结合的问题,这仍然需要很大的改造。

再补充一些,现实业务不只是 CURD ,PHP 的编程姿势主要是为 Web 服务,一旦有复杂的需求,用 PHP 实现起来会很蹩脚、或者浪费资源,比如游戏

#2 > php 很多业务场景 go 开发起来是无法胜任的

所以我觉得,你这个可能把现象搞错了。现象是 PHP 有众多轮子,并且未必需要高性能或者什么,用 go 去重新做成本收益不划算。就像好些人说企业级只能 Java 一样,其实不是 golang 或者其他不能搞,而是因为 Java 已经形成了成熟的产业链和社区,并且企业级的业务 Java 性能各方面也足够胜任。用 golang 或者其他语言去重造需要很长时间,而现实商业场景,没哪家资本愿意去推动这个。但如果是新团队重新造这些,是可以用 golang 的。字节系大量业务用 golang ,飞书应该也用得挺多的,人家有钱有资源有人才,就是可以搞。
除了极度性能场景是 c/cpp/rust 的天下,或者特殊专用领域,绝大部分的通用领域、绝大部分高并发高性能场景,golang 能搞、PHP 却未必能胜任。
140 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@lifei6671 #25

你们的运维兄弟是懂怎么挣钱的。。。
1 ... 6  7  8  9  10  11  12  13  14  15 ... 53  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   974 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 31ms · UTC 20:13 · PVG 04:13 · LAX 13:13 · JFK 16:13
Developed with CodeLauncher
♥ Do have faith in what you're doing.