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 的推荐实践.自己用了两年多也没遇到过什么问题.直到一天午睡后,同事扔过来一段奇怪的 ...
随机推荐
- ScreenToGif 录屏转git图片
ScreenToGif 一款开源的屏幕录制,允许您记录屏幕的选定区域.网络摄像头的实时信息或素描板上的实时绘图.之后,您可以编辑动画并将其保存为 gif.apng.视频.psd 或 png 图像. 官 ...
- Spring Boot 自动配置注解源码解析
前言 为什么Spring Boot这么火?因为便捷,开箱即用,但是你思考过为什么会这么便捷吗?传统的SSM架构配置文件至少要写半天,而使用Spring Boot之后只需要引入一个starter之后就能 ...
- Serverless 应用托管助力企业加速创新
作者: 熊峰 | 阿里云技术专家 云原生时代的 Serverless 应用托管架构 回顾过去十年,数字化转型将科技创新与商业元素不断融合.重构,重新定义了新业态下的增长极.商业正在从大工业时代的固化范 ...
- u-swipe-action 宽度计算的延迟导致组件加载时内部样式错误
https://toscode.gitee.com/umicro/uView/issues/I1Y50J 左图为电脑显示效果,右图为app显示效果. 原因:u-swipe-action 宽度计算的延迟 ...
- webpack升级-心得
- 解决navicat连接mysql数据库查询很慢的问题
1.背景: navicat连接数据库进行sql查询,每隔一段时间发现查询会变得很慢 2.原因: Mysql服务器端会定时清理长时间不活跃空闲的数据库连接,进行优化 3.解决方案: Navicat -右 ...
- 一文搞清楚Java中的包、类、接口
写在开头 包.类.接口.方法.变量.参数.代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分. Java中的包 ...
- MongoDB 根据多个条件批量修改
转载请注明出处: MongoDB 根据单个条件修改的sql 如下: db.collection_name.update({"userid":"1111111"} ...
- CSS3之transition
随着css3不断地发展,越来越多的页面特效可以被实现. 例如当我们鼠标悬浮在某个tab上的时候,给它以1s的渐进变化增加一个背景颜色.渐进的变化可以让css样式变化得不那么突兀,也显得交互更加柔和. ...
- Laravel - 模板中的url
<!-- 1, url --> <a href="{{url('/')}}">跳转到主页</a> <!-- 2,action 方法 ...
