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

> for flag print sleep 的那个循环一直占用着 CPU ,sleep 的实现是忙等,而后面的 for 循环从来都没有执行到,这是一种符合 spec 的行为

sleep 的实现是忙等,这个不对吧?它可不是纯 cpu spin 那种吧? print 也是有 io 的,也不是导致后面的 for 循环从来没有执行到的原因吧?
所以虽然后面的 for 被优化掉了,但我并不清楚具体什么原因导致的优化

> 两个 goroutine 同时对一个变量做读写操作,这个叫 data race ,当然是 undefined behavier
> 两个线程不能同时读写同一个变量,这个算基础知识吧

这个说法片面了吧~
data race 可能会造成不一致、undefined behavior ,但如果正确使用、并不会造成 ub 。
我代码里一些 flag 就是 data race 的,为了性能,一些简单的地方没必要都加锁,atomic 也是多余
160 天前
回复了 nightnotlate 创建的主题 生活 乖乖 原来退休工资比我想的多
OP 不用被气到,而且这跟煤矿辛苦没有关系:同样是煤矿,其他非编内人员,同样辛苦但待遇更差、仍然是不公平的。
我相信多数抱怨的人是觉得分配方案不够 average 和 balance ,并不是仇视你家人拿的多。
大家都心平气和些
160 天前
回复了 nnegier 创建的主题 互联网 大一统的账号体系可能不太靠谱现在?
用谷歌登录是不是也有同样的问题?这跟账号大一统没关系吧,相当于用于身份信息的那个中心 id 的故障问题,跟国内国外没关系。
@codehz #100

其实就是语言定位、取舍问题。c/cpp 这些是要把底层能力尽量留给开发者、开发者可以“肆意”掌控和进行性能优化,编译器自己优化性能的效率比肉眼要高得多。golang 的定位本来也不是像 c/cpp 那样极致性能与控制力,而是尽量在工程上让开发者能够舒服地做业务逻辑,所以写 go 也不需要考虑那么多。
@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 嗯嗯
161 天前
回复了 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 源码
完全没毛病,人家出钱了啊
162 天前
回复了 v2li32 创建的主题 PHP 讨论下 PHP 转 go 的水平
@guanhui07 #81

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

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

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

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

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

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

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

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

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

椅子这种还是得试坐,而且最好不只是简单试坐一会,至少模拟办公之类的坐上个把小时才好体验出来。否则八成都是人体不工学。
而且再怎么舒服、它也是久坐,解决不了根本问题,频繁起来走动、运动比任何椅子都强,而且可以治疗、康复颈肩腰痛。
165 天前
回复了 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{}) 清空超时关闭。
1 ... 6  7  8  9  10  11  12  13  14  15 ... 53  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4793 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 30ms · UTC 05:55 · PVG 13:55 · LAX 22:55 · JFK 01:55
Developed with CodeLauncher
♥ Do have faith in what you're doing.