码农先生

码农先生 查看完整档案

西安编辑  |  填写毕业院校博欣耀网络科技有限公司  |  后端研发 编辑 blog.zsboss888.com 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

码农先生 关注了用户 · 2020-12-09

TecOOler @bz1

关注 3

码农先生 提出了问题 · 2020-12-09

KODO mac版本图形工具太难用

吐槽一下,这个图形工具是巨难用,加载太慢太慢太慢。点击后 没有任何响应。不像大厂的出品,赶快优化吧。

关注 2 回答 1

码农先生 关注了用户 · 2020-11-13

李铭昕 @liming_5c6637b9ee87f

关注 5

码农先生 关注了专栏 · 2020-08-18

软件匠艺

「软件匠艺社区」旨在推广匠艺精神,帮助程序员快乐高效地编程。 更多优质内容请访问:http://CodingStyle.cn

关注 66

码农先生 关注了用户 · 2020-08-07

LNMPRG源码研究 @php7internal

一群热爱代码的人 研究Nginx PHP Redis Memcache Beanstalk 等源码 以及一群热爱前端的人
希望交流的朋友请加微信 289007301 注明:思否 拉到交流群,也可关注公众号:LNMPRG源码研究

《PHP7底层设计与源码分析》勘误https://segmentfault.com/a/11...

《Redis5命令设计与源码分析》https://item.jd.com/12566383....

景罗 陈雷 李乐 黄桃 施洪宝 季伟滨 闫昌 李志 王坤 肖涛 谭淼 张仕华 方波 周生政 熊浩含 张晶晶(女) 李长林 朱栋 张晶晶(男) 陈朝飞 巨振声 杨晓伟 闫小坤 韩鹏 夏达 周睿 李仲伟 张根红 景罗 欧阳 孙伟 李德 twosee

关注 11607

码农先生 关注了专栏 · 2020-08-04

Kaysen技术分享

分享关于Python、PHP、前端相关的文章

关注 4

码农先生 关注了用户 · 2020-07-25

汤青松 @songboy

《PHP Web安全开发实战》 作者

关注 5935

码农先生 赞了文章 · 2020-07-02

Swoole 内核开发备忘:内存管理优化(swString)

最新的优化,减少了从recv_bufferphp zval的内存copy,可以从recv_buffer变为PHP层的string类型变量,相当于直接从Socket接收缓存区中读取到了PHP层。

GitHub PR:https://github.com/swoole/swoole-src/pull/3423

swString 结构体

typedef struct _swString
{
    size_t length;
    size_t size;
    off_t offset;
    char *str;
    const swAllocator *allocator;
} swString;

在设计上,这几个字段的作用分别是:

  • size:内存容量长度,进行append写入操作时,如果有空余的空间,无需扩容。当实际数据长度等于size时,需要进行内存扩容,通过调用swString_extend()完成
  • length:实际数据长度,必须小于或等于size否则会内存越界,底层的swString_*系列函数会检查边界,避免越界读写
  • offset:操作游标,记录应用层实际处理数据的位置,offset必须小于或等于length

swString.jpg

新增了 allocator 字段,可以设置内存分配器,目前有3种。

  • SwooleG.std_allocator:标准的glibcmalloc
  • SWOOLE_G(php_allocator):PHP 的 emalloc
  • SWOOLE_G(zend_string_allocator)zend_string_alloc

数据处理

coroutine::Socket::recv_packet() 分为两个阶段从Socket中读取数据。

  1. 读取PacketHeader数据,可能是一个比较小的值,如 recv(sizeof(PacketHeader)),在头部中包含PacketLength字段,获取整个包的总长度
  2. 读取Payload数据,recv(PacketLength - sizeof(PacketHeader)

底层会预先将offset值设置为PacketLength,然后分段从网络收取数据,调用recv操作,将数据追加到缓存区,并更新length值。当length==offset时表示,接收完毕。coroutine::Socket::recv_packet()返回到应用层。这时应用层可以有两个操作。

  • 使用memcpy将数据从recv_buffer中读取出来,下一次调用recv_packet时,底层会自动调用swString_reduce()重置read_buffer缓存区,这会存在一次内存拷贝,但是复用一块内存的
  • 使用swString_pop()read_buffer->str整块内存弹出,在应用层使用,底层会自动分配新的内存,用于接收下一个包
zval zdata;
ssize_t retval = sock->recv_packet();

// 复制内存
ZVAL_STRINGL(&zdata, sock->get_read_buffer()->str, retval);

// 弹出内存
ZVAL_STR(&zdata, sw_get_zend_string(sock->pop_packet()));

本次的 zerocopy 就是使用第二种方式,read_buffer 使用了 SWOOLE_G(zend_string_allocator) 内存分配器,弹出来的 read_buffer->str 内存,正好是一个 zend_stringval,再使用 sw_get_zend_string(read_buffer->str) 就可以得到 zend_string 对象的内存地址,最后使用 ZVAL_STR() 或者 RETURN_STR() 可直接将 zend_string 对象作为 PHP 层函数调用的返回值。

查看原文

赞 6 收藏 1 评论 0

码农先生 关注了专栏 · 2020-06-05

Grace development

记录分享开发、学习中的点点滴滴

关注 4682

码农先生 关注了专栏 · 2020-03-30

PHP 学习总结

研读官网文档和网络优秀个人文章,对 PHP 编程相关作出学习总结。

关注 49

认证与成就

  • 获得 4 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-02-09
个人主页被 338 人浏览