(原创)C/C语言, 平台是debian10, grpc版本:grpc-c/1.25.0-dev grpc-c/8.0.0, 使用的例子是自带的例子GreeterClient

grpc Unary模式下客户端从开始连接到发送数据的主要流程

graph TD;
001(grpc_connector_connect #connector.cc:36 准备开始连接)-->002(chttp2_connector_connect #chttp2_connector.cc:225)

002(chttp2_connector_connect #chttp2_connector.cc:225)-->003(tcp_connect #tcp_client_posix.cc:350)

003(tcp_connect #tcp_client_posix.cc:350)-->004(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:294 调用connect连接服务器)

004(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:294 调用connect连接服务器)-->005(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:332)

005(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:332)-->006(grpc_core::LockfreeEvent::NotifyOn #lockfree_event.cc:110 设置grpc_core::LockfreeEvent write_closure的变量state_为回调为on_writable的closure)

006(grpc_core::LockfreeEvent::NotifyOn #lockfree_event.cc:110 设置grpc_core::LockfreeEvent write_closure的变量state_为回调为on_writable的closure)-->007(pollable_process_events #ev_epollex_linux.cc:903 连接上后有可写事件)

007(pollable_process_events #ev_epollex_linux.cc:903 连接上后有可写事件)-->008(grpc_core::LockfreeEvent::SetReady #lockfree_event.cc:243 调为on_writable函数)

008(grpc_core::LockfreeEvent::SetReady #lockfree_event.cc:243 调为on_writable函数)-->009(on_writable #tcp_client_posix.cc:244 在on_writable函数准备调用connected函数)

009(on_writable #tcp_client_posix.cc:244 在on_writable函数准备调用connected函数)-->010(connected #chttp2_connector.cc:193 在connected函数准备开始http2握手)

010(connected #chttp2_connector.cc:193 在connected函数准备开始http2握手)-->011(DoHandshake #handshaker.cc:249 开始执行握手)

011(DoHandshake #handshaker.cc:249 开始执行握手)-->012(CallNextHandshakerLocked #handshaker.cc:182 开始执行CallNextHandshakerLocked)

012(CallNextHandshakerLocked #handshaker.cc:182 开始执行CallNextHandshakerLocked)-->013(HttpConnectHandshaker::DoHandshake #http_connect_handshaker.cc:263 调用on_handshake_done)

013(HttpConnectHandshaker::DoHandshake #http_connect_handshaker.cc:263 调用on_handshake_done)-->014(on_handshake_done #chttp2_connector.cc:119 握手完了开始http2写)

014(on_handshake_done #chttp2_connector.cc:119 握手完了开始http2写)-->015(grpc_create_chttp2_transport #chttp2_transport.cc:3195 创建chttp2_transport)

015(grpc_create_chttp2_transport #chttp2_transport.cc:3195 创建chttp2_transport)-->016(grpc_chttp2_transport #chttp2_transport.cc:538 chttp2_transport的构造函数)

016(grpc_chttp2_transport #chttp2_transport.cc:538 chttp2_transport的构造函数)-->017(grpc_chttp2_act_on_flowctl_action #chttp2_transport.cc:2439 流量控制)

017(grpc_chttp2_act_on_flowctl_action #chttp2_transport.cc:2439 流量控制)-->018(WithUrgency #chttp2_transport.cc:2425 流量控制中对chttp2_transport的动作)

018(WithUrgency #chttp2_transport.cc:2425 流量控制中对chttp2_transport的动作)-->019(grpc_chttp2_initiate_write #chttp2_transport.cc:932 chttp2_transport写的初始化并调用真正的write_action_begin_locked写操作)

019(grpc_chttp2_initiate_write #chttp2_transport.cc:932 chttp2_transport写的初始化并调用真正的write_action_begin_locked写操作)-->020(write_action_begin_locked #chttp2_transport.cc:981 开始写)

020(write_action_begin_locked #chttp2_transport.cc:981 开始写)-->021(write_action #chttp2_transport.cc:1007 准备参数调用grpc_endpoint_write)

021(write_action #chttp2_transport.cc:1007 准备参数调用grpc_endpoint_write)-->022(grpc_endpoint_write #endpoint.cc:33 调用grpc_endpoint中的函数指针write指向tcp_write)

022(grpc_endpoint_write #endpoint.cc:33 调用grpc_endpoint中的函数指针write指向tcp_write)-->023(tcp_write #tcp_posix.cc:1093 调用tcp_flush #tcp_posix.cc:972 tcp_flush调用tcp_send #tcp_posix.cc:660并最终调用sendmsg, 发送的数据结构是struct msghdr)

grpc Unary模式下客户端从开始连接到接收数据的主要流程

graph TD;
001(grpc_connector_connect #connector.cc:36 准备开始连接)-->002(chttp2_connector_connect #chttp2_connector.cc:225)

002(chttp2_connector_connect #chttp2_connector.cc:225)-->003(tcp_connect #tcp_client_posix.cc:350)

003(tcp_connect #tcp_client_posix.cc:350)-->004(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:294 调用connect连接服务器)

004(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:294 调用connect连接服务器)-->005(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:332)

005(grpc_tcp_client_create_from_prepared_fd #tcp_client_posix.cc:332)-->006(grpc_core::LockfreeEvent::NotifyOn #lockfree_event.cc:110 设置grpc_core::LockfreeEvent write_closure的变量state_为回调为on_writable的closure)

006(grpc_core::LockfreeEvent::NotifyOn #lockfree_event.cc:110 设置grpc_core::LockfreeEvent write_closure的变量state_为回调为on_writable的closure)-->007(pollable_process_events #ev_epollex_linux.cc:903 连接上后有可写事件)

007(pollable_process_events #ev_epollex_linux.cc:903 连接上后有可写事件)-->008(grpc_core::LockfreeEvent::SetReady #lockfree_event.cc:243 调为on_writable函数)

008(grpc_core::LockfreeEvent::SetReady #lockfree_event.cc:243 调为on_writable函数)-->009(on_writable #tcp_client_posix.cc:244 在on_writable函数准备调用connected函数)

009(on_writable #tcp_client_posix.cc:244 在on_writable函数准备调用connected函数)-->010(connected #chttp2_connector.cc:193 在connected函数准备开始http2握手)

010(connected #chttp2_connector.cc:193 在connected函数准备开始http2握手)-->011(DoHandshake #handshaker.cc:249 开始执行握手)

011(DoHandshake #handshaker.cc:249 开始执行握手)-->012(CallNextHandshakerLocked #handshaker.cc:182 开始执行CallNextHandshakerLocked)

012(CallNextHandshakerLocked #handshaker.cc:182 开始执行CallNextHandshakerLocked)-->013(HttpConnectHandshaker::DoHandshake #http_connect_handshaker.cc:263 调用on_handshake_done)

013(HttpConnectHandshaker::DoHandshake #http_connect_handshaker.cc:263 调用on_handshake_done)-->014(on_handshake_done #chttp2_connector.cc:147 握手完了开始http2读)

014(on_handshake_done #chttp2_connector.cc:147 握手完了开始http2读)-->015(grpc_chttp2_transport_start_reading #chttp2_transport.cc:3212 通过GRPC_CLOSURE_SCHED调用read_action_locked)

015(grpc_chttp2_transport_start_reading #chttp2_transport.cc:3212 通过GRPC_CLOSURE_SCHED调用read_action_locked)-->016(read_action_locked #chttp2_transport.cc:2568 调用continue_read_action_locked)

016(read_action_locked #chttp2_transport.cc:2568 调用continue_read_action_locked)-->017(continue_read_action_locked #chttp2_transport.cc:2579 调用grpc_endpoint_read)

017(continue_read_action_locked #chttp2_transport.cc:2579 调用grpc_endpoint_read)-->018(grpc_endpoint_read #endpoint.cc:28 调用grpc_endpoint中的read指针函数tcp_read)

018(grpc_endpoint_read #endpoint.cc:28 调用grpc_endpoint中的read指针函数tcp_read)-->019(tcp_read #tcp_posix.cc:636 调用notify_on_read把read_closure的变量state_设置为tcp->read_done_closure)

019(tcp_read #tcp_posix.cc:636 调用notify_on_read把read_closure的变量state_设置为tcp->read_done_closure)-->020(tcp_handle_read #tcp_posix.cc:619 epollin事件触发tcp_handle_read, epollin事件触发tcp_handle_read, 调用tcp_continue_read调用tcp_continue_read)

020(tcp_handle_read #tcp_posix.cc:619 epollin事件触发tcp_handle_read, epollin事件触发tcp_handle_read, 调用tcp_continue_read调用tcp_continue_read)-->021(tcp_continue_read #tcp_posix.cc:594 申请存放读内容的内存或者执行读操作, 此处申请内存)

021(tcp_continue_read #tcp_posix.cc:594 申请存放读内容的内存或者执行读操作, 此处申请内存)-->022(grpc_resource_user_alloc_slices #resource_quota.cc:1010 申请tcp->incoming_buffer内存)

022(grpc_resource_user_alloc_slices #resource_quota.cc:1010 申请tcp->incoming_buffer内存)-->023(grpc_resource_user_alloc #resource_quota.cc:939 上锁并调用resource_user_alloc_locked)

023(grpc_resource_user_alloc #resource_quota.cc:939 上锁并调用resource_user_alloc_locked)-->024(resource_user_alloc_locked #resource_quota.cc:905 调用allocate_closure的callback函数ru_allocate)

024(resource_user_alloc_locked #resource_quota.cc:905 调用allocate_closure的callback函数ru_allocate)-->025(ru_allocate #resource_quota.cc:485 调用rq_step_sched并把resource_user加入GRPC_RULIST_AWAITING_ALLOCATION对应的list)

025(ru_allocate #resource_quota.cc:485 调用rq_step_sched并把resource_user加入GRPC_RULIST_AWAITING_ALLOCATION对应的list)-->026(rq_step_sched #resource_quota.cc:296 调用rq_step_closure的callback函数rq_step)

026(rq_step_sched #resource_quota.cc:296 调用rq_step_closure的callback函数rq_step)-->027(rq_step #resource_quota.cc:281 调用rq_alloc)

027(rq_step #resource_quota.cc:281 调用rq_alloc)-->028(rq_alloc #resource_quota.cc:361 调用on_allocated这个list上所有的callback函数, 通过堆栈可以找到一个函数ru_allocated_slices)

028(rq_alloc #resource_quota.cc:361 调用on_allocated这个list上所有的callback函数, 通过堆栈可以找到一个函数ru_allocated_slices)-->029(ru_allocated_slices #resource_quota.cc:599 调用了ru_alloc_slices申请内存, 然后调用on_done的callback函数tcp_read_allocation_done, tcp_read_allocation_done在grpc_tcp_create设置)

029(ru_allocated_slices #resource_quota.cc:599 调用了ru_alloc_slices申请内存, 然后调用on_done的callback函数tcp_read_allocation_done, tcp_read_allocation_done在grpc_tcp_create设置)-->030(tcp_read_allocation_done #tcp_posix.cc:582 调用真正的读函数tcp_do_read, 在tcp_do_read中调用recvmsg 第二个参数结构是struct msghdr)

Unary模式下客户端从开始连接到发送接收数据的主要流程的更多相关文章

  1. Unary模式下客户端创建 default-executor 和 resolver-executor 线程和从启动到执行grpc_connector_connect的主要流程

    (原创)C/C/1.25.0-dev grpc-c/8.0.0, 使用的例子是自带的例子GreeterClient 创建 default-executor 和 resolver-executor 线程 ...

  2. grpc Unary模式下客户端创建insecure channel的主要流程

    (原创)C/C/1.25.0-dev grpc-c/8.0.0, 使用的例子是自带的例子GreeterClient grpc Unary模式下客户端创建insecure channel的主要流程 gr ...

  3. 安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制

    安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制 socket 连接采用流的方式进行发送接收数据,采用thread线程的方式. 什么是线程?  详细代码介 ...

  4. 烂泥:openvpn tun模式下客户端与内网机器通信

    本文由秀依林枫提供友情赞助,首发于烂泥行天下 前两篇文章我们介绍了有关openvpn的搭建与配置文件的讲解,这篇文章我们再聊介绍下,在tun模式下openvpn客户端如何与内网机器通信的问题. 一.实 ...

  5. golang连接activemq,发送接收数据

    介绍 使用golang连接activemq发送数据的话,需要使用一个叫做stomp的包,直接go get github.com/go-stomp/stomp即可 代码 生产者 package main ...

  6. vm虚拟机里的桥接模式下“复制物理网络连接状态”作用

    前提:真实主机可以上网 勾选,虚拟机也可以上网 不勾选,虚拟机不可以上网

  7. 简单记录下@RequestBody(关于它和@RequestParam接收数据方式的拓展)

    内容参考自博客:https://blog.csdn.net/ff906317011/article/details/78552426 这个标注是用来注释controller中的请求方法中的参数的,那么 ...

  8. NAT模式下VMware中CentOS7无法连接外网的解决方法

    故障现象 ----------------------------------------------------------------------------------------------- ...

  9. 痞子衡嵌入式:i.MXRT连接特殊Octal Flash时(OPI DTR模式下反转字节序)下载与启动注意事项(以MX25UM51245为例)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是OPI DTR模式下反转字节序的Octal Flash在i.MXRT下载与启动注意事项. 在恩智浦官方参考设计板 MIMXRT595-E ...

随机推荐

  1. 8-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087558.html 咱用这个编写 ,版本都无所谓哈,只要自己有就可以,不同版本怎么打开 https://www.cnb ...

  2. linux高性能服务器编程 (六) --高级I/O函数

    第六章 高级I/O函数 Linux提供了很多高级的I/O函数,它不是基础的I/O函数(open/read) 1.创建文件描述符的函数比如:pipe.dup/dup2函数 2.读写数据的函数比如:rea ...

  3. MVC框架模式和Javaweb经典三层架构

    一.MVC设计模式 1.MVC的概念 首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(Vie ...

  4. 第01组 Alpha冲刺(2/6)

    队名:007 组长博客: https://www.cnblogs.com/Linrrui/p/11861798.html 作业博客: https://edu.cnblogs.com/campus/fz ...

  5. Excel中筛选两个表中相同的数据和快速填充一列的公式

    将两个工作表放在一个文件中,使用if函数和countif函数判断 =if(判断条件countif(区域,条件),真值,[假值]) 实例 =if(countif(Sheet2!$A$1:$A$44,A2 ...

  6. jQuery实现列表框双向选择操作

    对列表框的操作经常碰到过这样的应用:从左侧的列表框中选中要选的项添加到右侧列表框中,然后提交最终选择的项,对误操作而选中的项还可以执行移除操作.在很多系统中应用比如说求职网站的选择意向工作地区,QQ好 ...

  7. 【Dubbo】带着问题看源码:什么是SPI机制?Dubbo是如何实现的?

    什么是SPI? ​ 在Java中,SPI全称为 Service Provider Interface,是一种典型的面向接口编程机制.定义通用接口,然后具体实现可以动态替换,和 IoC 有异曲同工之妙. ...

  8. [源码分析]HashSet 和LinkedHashSet

    特性 HashSet是一个可存储不重复元素的容器,底层实现依赖 HashMap,所以在添加,删除,查找元素时的时间复杂度均为 O(1). 构造方法,初始化内部的HashMap public HashS ...

  9. annotation processor 为啥没有被调用?

    Android Studio 3.5 使用@AutoService(Processor.class)注册annotation processor Android Plugin for Gradle:  ...

  10. (转)Loadrunner教程--常用操做流程

    1loadrunner压力测试一般使用流程 1.1loadrunner压力测试原理 本质就是在loadrunner上模拟多个用户同时按固定行为访问web站点.其中固定行为在loadrunner中是通过 ...