2021-07-30 JVM hang之写pipe阻塞

发展方向越来越明晰了呢:
掌握一个特定的开发领域,熟练且精通。什么叫熟练,就是在这个领域下,能扶起来一个应用,达成你想要的功能
但向深度,往哪里深呢,我还是更喜欢OS,弄清OS,几乎没问题能挡住你,为什么不向一个框架深入呢?以我目前的认知,要熟悉一个框架就是看说明书
另一方向,需要学习大量的开源代码来掌握编程模式,编程套路
更深一些,即算法,它可以有理论依据的、巧妙地去解决一个复杂问题,而不是去凑(数学之美这本书告诉我的),比如一个有限状态机的实现过程,比如看看Spring是如何使用IoC来实现对象组合的(需要的是思想,设计思想,不是实现细节),比如说,Apache HTTPClient是如何探测TCP连接是否新鲜的(我想这个即使在C语言中也是通用的)。

问题描述

好了,切入正题。
我们的测试又卡住了。对surefire JVM,jstack看出main线程在RUNNABLE, 并且方法栈顶是在writeBytes() ,一个native method处,转化线程ID到Linux TaskId,再来一剂strace,果然看到write(1, "8,3 UTF-8....., 216)停在这里不返回了,显然是写阻塞了。
此时,我cat /proc/taskId/1,把文件内容读出来,这个JVM进程也就结束了,还输出个BYE.

问题分析

可是1不是stdout吗?这玩意还能阻塞?
它真的是stdout吗?你看这个进程到控制台输出了吗?没有,查看task的fd,1果然是个pipe文件,dup忘了…
pipe写是同步的吗?这真没想过,一个管道,有大小没有?
pipe man手册

If a process attempts to read from an empty pipe, then read(2)
will block until data is available. If a process attempts to
write to a full pipe (see below), then write(2) blocks until
sufficient data has been read from the pipe to allow the write to
complete. Nonblocking I/O is possible by using the fcntl(2)
F_SETFL operation to enable the O_NONBLOCK open file status flag.
The communication channel provided by a pipe is a byte stream:
there is no concept of message boundaries.

如果一个进程尝试从一个空pipe去读,则read系统调用就会阻塞直到有数据。如果一个进程尝试向一个满pipe写入数据,则write系统调用会阻塞直到有足够的数据被读走允许写。非阻塞IO是允许通过系统调用fctnl系统调用的F_SETFL操作使能O_NONBLOCK打开文件状态标记。
pipe提供的通信channel是一个stream,没有消息边界的概念。
在Linux2.6.35之后,pipe默认大小为16个页大小,64KB,但是又有个最大pipe大小, /proc/sys/fs/pipe-max-size 为1MB, 那么这个满,是以谁为准呢?StackOverFlow 中指出:可以通过fcntl指定F_SETPIPE_SZ,否则为默认64KB.

In Linux versions before 2.6.11, the capacity of a pipe was the
same as the system page size (e.g., 4096 bytes on i386).
Since Linux 2.6.11, the pipe capacity is 16 pages (i.e., 65,536 bytes
in a system with a page size of 4096 bytes). Since Linux 2.6.35,
the default pipe capacity is 16 pages, but the capacity can be
queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ
operations. See fcntl(2) for more information.
The following ioctl(2) operation, which can be applied to a file
descriptor that refers to either end of a pipe, places a count of
the number of unread bytes in the pipe in the int buffer pointed
to by the final argument of the call:
ioctl(fd, FIONREAD, &nbytes);
The FIONREAD operation is not specified in any standard, but is
provided on many implementations.

结果显示当然是同步的,否则也不会阻塞,那么读的那一端为啥子不读了?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值