BIO系统调用strace查看IO阻塞

news/2025/2/26 6:22:42

BIO服务端例子

服务端监听8090端口,每一个客户端用一个线程处理,不断的获取客户端的输入数据并打印

java">import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author mubi
 * @Date 2020/6/25 18:54
 */
public class TestSocket {
    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = new ServerSocket(8090);
        System.out.println("step1 new ServerSocket(8090)");
        while(true){
            final Socket client = serverSocket.accept();
            System.out.println("step2 client:" + client.getPort());
            new Thread(()->{
                try{
                    InputStream in = client.getInputStream();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
                    while (true){
                        System.out.println(bufferedReader.readLine());
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }).start();
        }

    }
}

nc命令去连接服务端

java">nc localhost 8090

strace命令追踪系统调用

java">javac TestSocket.java
strace -ff -o ./stracefile java TestSocket

ServerSocket启动过程

  1. socket系统调用, 得到文件描述符,如 fd5
  2. bind端口
  3. listen,文件描述符
  4. accept(阻塞状态), 有客户端连接得到新的socket, 产生文件描述符 如 fd6,fd7

在这里插入图片描述

在这里插入图片描述

查看进程下所有线程

通过进程ID号能知道有多少个线程(linux的/proc/<pid>/task目录下)

在这里插入图片描述

补充:linux创建线程是clone系统调用,在主线程的stracefile中可以看到

java">clone(child_stack=0x7fd8d8508ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_     PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fd8d85099d0, tls=0x7fd8d8509700, child_tidptr=0x7fd8d85099d0) = 4787

netstat查看tcp相关

Listen,ESTABLISHED状态的TCP

在这里插入图片描述

文件描述符的查看

在工作目录会看到很多stracefile,以.线程id结尾;本地nc命令起的56544端口的客户端连接,vim stracefile.4772(4772是服务端开启的主线程),可以找到accept语句

java">accept(5, {sa_family=AF_INET6, sin6_port=htons(56544), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 6
fcntl(6, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(6, F_SETFL, O_RDWR)               = 0
lseek(3, 62493071, SEEK_SET)            = 62493071
read(3, "PK\3\4\n\0\0\10\0\0000\211|L9\267\215\270R\6\0\0R\6\0\0;\0\0\0", 30) = 30
lseek(3, 62493160, SEEK_SET)            = 62493160
read(3, "\312\376\272\276\0\0\0004\0:\7\0!\n\0\v\0\"\t\0\10\0#\n\0\1\0$\t\0\v\0"..., 1618) = 1618
write(1, "step2 client:56544", 18)      = 18

man 2 accept了解到 accept 的返回:系统会产生一个文件描述符,关联接收到的socket文件

java">RETURN VALUE
       On success, these system calls return a nonnegative integer that is a descriptor for the accepted socket.  On error,  -1  is returned, and errno is set appropriately.

从上可以看出是文件描述符6的一个文件,即代表了连接上的一个客户端socket(在/proc/<pid>/fd目录下可见,pid为Java程序进程ID,本地同jps命令看到的程序运行ID):

在这里插入图片描述

  • strace给客户端起的线程,会阻塞在recvfrom接收数据上(查看上文clone产生的线程tid=4787),vim stracefile.4787可以看到阻塞在recvfrom(6,上,即阻塞在read客户端socket fd上
java">set_robust_list(0x7fd8d85099e0, 24)     = 0
gettid()                                = 4787
rt_sigprocmask(SIG_BLOCK, NULL, [QUIT], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [HUP INT ILL BUS FPE SEGV USR2 TERM], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
futex(0x7fd8f000b354, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fd8f000b350, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7fd8f000b328, FUTEX_WAKE_PRIVATE, 1) = 1
sched_getaffinity(4787, 32, [1, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) = 32
sched_getaffinity(4787, 32, [1, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) = 32
(0x7fd8d8409000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd8d8409000
mprotect(0x7fd8d8409000, 12288, PROT_NONE) = 0
lseek(3, 30054856, SEEK_SET)            = 30054856
read(3, "PK\3\4\n\0\0\10\0\0006\211|L\24w\0067E\3\0\0E\3\0\0\27\0\0\0", 30) = 30
lseek(3, 30054909, SEEK_SET)            = 30054909
read(3, "\312\376\272\276\0\0\0004\0-\t\0\6\0\34\n\0\7\0\35\t\0\32\0\36\n\0\37\0\33\n\0"..., 837) = 837
lseek(3, 30056639, SEEK_SET)            = 30056639
read(3, "PK\3\4\n\0\0\10\0\0B\211|L\305SF\t\265\r\0\0\265\r\0\0 \0\0\0", 30) = 30
lseek(3, 30056701, SEEK_SET)            = 30056701
read(3, "\312\376\272\276\0\0\0004\0\242\n\0Y\0Z\n\0-\0[\t\0,\0\\\t\0,\0]\t\0"..., 3509) = 3509
recvfrom(6, "helloABC\n", 8192, 0, NULL, NULL) = 9
ioctl(6, FIONREAD, [0])                 = 0
write(1, "helloABC", 8)                 = 8
write(1, "\n", 1)                       = 1
recvfrom(6,

http://www.niftyadmin.cn/n/5868190.html

相关文章

Kubernetes 1.29升级至1.31版本笔记

一、概述 之前安装了kubernetes 1.29&#xff08;参见&#x1f449;&#xff1a;使用kubeadm安装Kubernetes1.29&#xff09;。 本次计划将该集群升级为&#x1f449;1.31版本。 Kubernetes版本表示方式&#xff1a; Kubernetes版本表示为x.y.z&#xff0c;其中x是主版本&…

Django 视图函数中的 `response` 对象及类型扩写

Django 视图函数中的 response 对象及类型扩写 在 Django 中&#xff0c;视图函数不仅负责处理请求&#xff0c;还负责生成响应。响应可以是以多种格式返回给客户端的数据&#xff0c;包括 HTML 页面、重定向、JSON 数据、文件等。以下是关于 Django 中几种常见响应类型的详细…

那些排序算法和初始序列的状态有关

那些排序算法对序列的初始状态有关 比如&#xff0c;冒泡排序和插入排序&#xff0c;在最好情况下&#xff0c;也就是序列已经排好序的时候&#xff0c;时间复杂度是O(n)&#xff0c;而最坏情况下是O(n)。这说明它们的性能确实和初始状态有关。快速排序的话&#xff0c;如果每次…

DeepSeek AI智能运营:重构企业效率的范式革命

文章目录 一、企业级智能运营的深度实践1. 智慧园区运营&#xff1a;AI驱动的全流程重构2. 金融行业&#xff1a;合规审核自动化 二、垂直行业场景突破1. 制造业智能质检系统2. 教育行业智能伴学 三、核心技术架构演进1. 推理加速架构2. 多模态数据处理 四、开发工具链实践1. V…

基于Prometheus与Grafana构建实时监控与告警体系,保障微服务稳定性!

全文目录&#xff1a; 开篇语前言为什么选择Prometheus和Grafana&#xff1f;Prometheus&#xff1a;功能强大&#xff0c;专注于时序数据Grafana&#xff1a;数据可视化的艺术 构建实时监控与告警体系的步骤1. 安装Prometheus1.1 安装Prometheus1.2 配置Prometheus监控目标1.3…

Flash-03

1-问题&#xff1a;Flash软件画两个图形&#xff0c;若有部分重合则变为一个整体 解决方法1&#xff1a;两个图形分属于不同的图层 解决方法2&#xff1a;将每个图形都转化为【元件】 问题2&#xff1a;元件是什么&#xff1f; 在 Adobe Flash&#xff08;现在称为 Adobe Anim…

自然语言处理(NLP):文本向量化从文字到数字的原理

在人工智能领域&#xff0c;尤其是自然语言处理&#xff08;NLP&#xff09;中&#xff0c;将文本信息转化为机器可以理解的形式是一个至关重要的步骤。本文探讨如何将文本转换为向量表示的过程&#xff0c;包括分词、ID映射、One-hot编码以及最终的词嵌入&#xff08;Embeddin…

Anaconda 与 Jupyter Notebook 的结合使用

1. 引言 Jupyter Notebook 是一种非常流行的交互式计算环境&#xff0c;广泛应用于数据科学、机器学习和学术研究领域。它允许用户将代码、文本、可视化和数学公式结合在一个文档中&#xff0c;极大地提高了分析过程的可视性和可重复性。Anaconda 作为 Python 生态中最为流行的…