golang 中使用 writev (sendmsg) 系统调用来一次发送多块数据
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
writev,或者说 sendmsg 等系统调用,能够发送多个数据块。从节约系统调用次数的角度说,这个 api 非常好。
下面演示如何在 golang 中使用 sendmsg 系统调用:
func sendmsg(conn net.Conn, buf1 []byte, buf2 []byte){
// 我的应用里正好只有两块数据,所以偷懒了
// 先获得 socket fd
rawConn, err := sysconn.SyscallConn()
if err != nil {
log.Error(err.Error())
return
}
var sockfd uintptr
err = rawConn.Control(func(fd uintptr) {
sockfd = fd
})
if err != nil {
log.Error(err.Error())
return
}
//
//send msg
var ivs [2]syscall.Iovec
start := 0
total := len(buf1) + len(buf2)
var cnt uint64 = 2
for start < total {
if start < len(buf1) {
ivs[0].Base = &buf1[start]
ivs[0].Len = uint64(len(buf1) - start)
ivs[1].Base = &buf2[0]
ivs[1].Len = uint64(len(buf2))
} else {
cnt = 1
ivs[0].Base = &buf2[start-len(buf1)]
ivs[0].Len = uint64(len(buf1)+len(buf2)-start)
}
var msghdr = syscall.Msghdr{
Iov: &ivs[0],
Iovlen: cnt,
}
var flags uintptr = 0x4000000 // 零拷贝标志
r, _, e := syscall.RawSyscall(syscall.SYS_SENDMSG, sockfd, uintptr(unsafe.Pointer(&msghdr)), flags)
if e != 0 {
log.Error(syscall.Errno(e).Error())
return
}
start += int(r)
}
}
测试发现:
- 通过 sendmsg,减少了 conn.Write() 的调用次数,服务的性能明显上升;
- 当 buf1, buf2 对应的缓冲区,来自于 mmap() 调用时,零拷贝就生效了;
- 因为我测试的数据只有 2kb,所以使用零拷贝比不使用零拷贝更慢。(可能超过一定规模会更快)
golang 中使用 writev (sendmsg) 系统调用来一次发送多块数据的更多相关文章
- TCP层sendmsg系统调用的实现分析
概述 sendmsg系统调用在tcp层的实现是tcp_sendmsg函数,该函数完成以下任务:从用户空间读取数据,拷贝到内核skb,将skb加入到发送队列的任务,调用发送函数:函数在执行过程中会锁定控 ...
- 套接字之sendmsg系统调用
sendmsg系统调用允许在用户空间构造消息头和控制信息,用此函数可以发送多个数据缓冲区的数据,并支持控制信息:当调用进入内核后,会将用户端的user_msghdr对应拷贝到内核的msghdr中,然后 ...
- golang中的race检测
golang中的race检测 由于golang中的go是非常方便的,加上函数又非常容易隐藏go. 所以很多时候,当我们写出一个程序的时候,我们并不知道这个程序在并发情况下会不会出现什么问题. 所以在本 ...
- 基础知识 - Golang 中的正则表达式
------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...
- golang中的reflect包用法
最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...
- Golang中的坑二
Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...
- Golang 中的坑 一
Golang 中的坑 短变量声明 Short variable declarations 考虑如下代码: package main import ( "errors" " ...
- google的grpc在golang中的使用
GRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x. 前面写过一篇golang标准库的rpc包的用法,这篇文章接着讲一 ...
- Golang中Struct与DB中表字段通过反射自动映射 - sqlmapper
Golang中操作数据库已经有现成的库"database/sql"可以用,但是"database/sql"只提供了最基础的操作接口: 对数据库中一张表的增删改查 ...
- Golang中WaitGroup使用的一点坑
Golang中WaitGroup使用的一点坑 Golang 中的 WaitGroup 一直是同步 goroutine 的推荐实践.自己用了两年多也没遇到过什么问题.直到一天午睡后,同事扔过来一段奇怪的 ...
随机推荐
- Flutter加固原理及加密处理
引言 为了保护Flutter应用免受潜在的漏洞和攻击威胁,加固是必不可少的措施之一.Flutter加固原理主要包括代码混淆.数据加密.安全存储.反调试与反分析.动态加载和安全通信等多个方面.通过综 ...
- 智能电视APP鲜时光,如何应用AB测试打造极致的用户观看体验?
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 数字技术的发展让智能电视普及率大幅提升,2023年智能电视的市场渗透率已超90%,与智能电视相匹配的各类应用 ...
- Solon 开发进阶,四、启动参数说明
Solon 开发进阶 一.插件扩展机制 二.体外扩展机制 三.常用配置说明 四.启动参数说明 五.全局异常订阅 启动参数,在应用启动后会被静态化(为了内部更高效的利用).比如,想通过体外扩展加载配置, ...
- PPT 笔刷:让你的PPT充满视觉冲击
其实就是下载的AI效果 辅助文字展示 辅助图片展示 创意展示图片,增强视觉冲击力 使用 删除外面的边框 https://www.bilibili.com/video/BV1ha411g7f5?p=16
- 【python爬虫】bs4遍历、搜索文档树 bs4使用css选择器 selenium基本使用 selenium查找标签 selenium执行js代码
目录 上节回顾 今日内容 0 bs4遍历文档树 1 bs4搜索文档树 1.1 find方法的其他参数 2 css选择器 3 selenium基本使用 4 无界面浏览器 4.1 模拟登录百度 5 sel ...
- KB21N、KB24N作业分配与冲销
一.KB21N 调用BAPI:BAPI_ACC_ACTIVITY_ALLOC_POST 经测试,分配订单时行项目一次性最多传332条数据 "------------------------- ...
- 2018年第九届 蓝桥杯A组 C/C++决赛题解
蓝桥杯历年国赛真题汇总:Here 1.三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5.1, 7.2) 求该三角形的面积. 注意,要提交的是 ...
- AtCoder Beginner Contest 197(Sponsored by Panasonic) Person Editorial
A - Rotate 先输出第二和第三个字符,然后再输出第一个字符即可 B - Visibility 以 \((x,y)\) 作为起点向4个方向探索不是 # 的点,注意一下会在\((x,y)\)重复计 ...
- OKR之剑·实战篇06:OKR致胜法宝-氛围&业绩双轮驱动(下)
作者:vivo 互联网平台产品研发团队 本文是<OKR 之剑>系列之实战第 6 篇-- 本文介绍团队营造氛围的方法与实践.在业绩方面的探索与输出,在两方面分别总结了一些经验分享给大家. 一 ...
- Intellij IDEA安装与配置教程(Windows版)
Intellij IDEA(简称IDEA)是Java语言的集成开发环境,在业界公认为是一款优秀的Java开发工具.分为Community社区版(免费)和Untimate终极版(付费). IDEA是一款 ...