九维我操你爹
#北京を卒業しよう
片付けをしていて、思い出の物やすっかり忘れていた物が出てくると、つい見入っちゃう——こういうの、皆さんもよく分かるよね。
いま、家にある日本語関連の本を全部整理し終わったところなんだけど、ここまで支えてくれた本たちには「ありがとう」と言いたい(半分以上は積読本だけどな)。

……あっ、昔の試験用紙や練習帳も見つけた。パラパラめくってみたら、思わず笑っちゃった。ふふふ。
この8年間の重さ、そして自分の成長を、改めて感じられた。
知能がなさすぎにも限度ってあるよね

我:一个半小时后叫我起床(现在时刻下午一点)
苹果智障:好的,已经定好了下午一点半的闹钟
昨晚上在淘宝下单了轻洗到家的洗鞋服务。这个好像要他们客服处理订单以后才能预约上门取件的时间。所以现在单纯只是付了钱,连服务资格都还没生效,然后早上就接到了下面这通电话:

(陌生来电):你好,轻洗到家的,有需要保洁服务的吗?
:没有没有没有,我没有说想收到营销电话啊
(陌生来电):……
(机械):请您对我本次的服务做出评价,非常满意请按1……不满意请按3
:3
(机械):请您对我本次的服务做出评价,非常满意请按1……不满意请按3
:3
(机械):请您对我本次的服务做出评价,非常满意请按1……不满意请按3
:3
(电话被挂断了)

这还没开始服务就把好感败光了啊?不仅骚扰用户,简直就是不要脸啊😅
梓瑶在上周分享的 rust x SIGPIPE 的 issue 很有意思: https://t.me/ziyao233channel/3879
issue: https://github.com/rust-lang/rust/issues/62569

这里涉及了命令行软件和服务端软件的一些默认实践,我翻了一下几年前的笔记恢复了记忆。

服务端软件(socket 网络编程)通过 write (writev/sendto/sendmsg/sendmmsg) syscall 发送 tcp 流量,这里有个几乎无法避免的情况是,进程正在 write(sock),对端的 tcp reset 飞过来了,内核会抛出 SIGPIPE 信号通知进程这个 socket 不可写。

这个行为对于服务端软件是完全有害且多余。
- 说有害是因为 SIGPIPE 信号的默认处理是崩掉进程,然而 socket 收到 tcp reset 本来就是预期之内的情况,所以必须忽视 SIGPIPE。
- 说多余是因为忽视 SIGPIPE 之后,write syscall 返回 EPIPE 错误码,进程不可能错过这个报错,“正在给一个已经收到 tcp reset 的 socket 写数据” 的这个信息量没有得到任何丢失,反而由于同步化的 EPIPE 返回简化了信号处理(否则 pthread_sigmask + sigtimedwait 是有多想不开)

因此写网络程序直接 ignore SIGPIPE 百利无害,此事在 Unix Network Programming 中亦有记载,UNP 还是太权威了[1]

既然如此那为何要设计 SIGPIPE,全部用 EPIPE 错误码不就好了?答:unix 历史遗留 https://stackoverflow.com/questions/8369506/why-does-sigpipe-exist
这里带出了 SIGPIPE 的(几乎唯一?)需要抛出的场景,考虑命令行:
$ (echo 1; sleep 1; echo 2) | head -1
1
~ $ echo "${PIPESTATUS[@]}"
141 0


管道下游的 head -1 读到第一个 echo 1 的输出就退出进程了,关闭了 pipe_r,导致 pipe_w 不可写,上游的 echo 2 再 write(pipe_w) 的时候会遭遇 SIGPIPE 中止进程。
古典的 unix 命令行要求此时在 retval 里反映信号,141 == 128 + SIGPIPE(13)。

这个要求导致我们不能无脑 ignore SIGPIPE,否则看起来有点业余。(当然可以在命令行软件里看到 EPIPE 再手动 raise SIGPIPE / return 141

所以 rust 目前默认 ignore SIGPIPE 就常常会使 rust 编写的命令行工具在本应该返回 141 return code 时候返回 0(again,这是可以仔细处理好的:在 EPIPE 时 return 141

如果去看下 go 是怎么处理的,会发现它(貌似)更智慧一点:
A write to a broken pipe on file descriptors 1 or 2 (standard output or standard error) will cause the program to exit with a SIGPIPE signal. A write to a broken pipe on some other file descriptor will take no action on the SIGPIPE signal, and the write will fail with a syscall.EPIPE error.

https://pkg.go.dev/os/signal#hdr-SIGPIPE

更能照顾到绝大多数场景。

不过在 gdb 调试 go 进程时,由于 SIGPIPE 没有被 ignore,会触发 ptrace 的 signal-delivery-stop,很烦,但都是非常细微的 debugger 细节,正常人类不用管。。。

[1] https://flylib.com/books/en/3.225.1.83/1/

(再不分享点技术内容就要沦陷为飞升为男同交友频道了)
苹果测试工程师的日常
おじいさんの近況は、もうこれから知ることができないのだろう——そう思うと胸が痛む。 おじいさんは、かつてお世話になった民宿のホスト有賀さん。私が「通訳できますよ」と申し出ても、頑なに翻訳アプリを使って、全員と一人ずつ向き合って話そうとしてくれた。 まぁ自動翻訳だけではほとんど通じなくて、結局、私が通訳することになった。それでも、言葉が通じなくても“ちゃんと自分で話したい”と真摯に向き合ってくれる姿に、私たちは皆、心を打たれた。 旅が終わったあとも、皆でずっとおじいさんのことを気にかけ続けていた。ハガキを…
看到这条消息很难过,不知道之后要怎么才能看到有賀先生的近况了——有賀先生是我曾经日本旅行时住过的一间民宿的主人,尽管我提出了我可以在同行的伙伴和他之间作为翻译,但是老先生还是坚持用手机上的翻译器和我们每个人聊天。
尽管自动翻译有很多的错误,还是需要我来帮忙补充,但老先生即便是语言不通也坚持要自己面对面和每个人沟通的姿态感动了我们所有人。旅行之后我们仍时常挂念着他,有朋友写过明信片寄给他,我也会时不时地访问他的博客来了解他的近况。
有賀先生几乎每天都会写一篇博客,我想他一定有收到平台将要关闭服务的提醒吧,不知道他是否曾经在某一篇博客中说明了未来博客会迁移到什么地方。但作为一名不合格的读者,我错过了他最后的博客,也错过了征得他的同意,并为他的博客存档的机会。
等我知道时,一切已经无法挽回了。互联网上能找到的最后的存档停留在 6 月 18 号,之后整整 5 个月的内容恐怕都已无从恢复。
Back to Top