https://bbs.huaweicloud.com/blogs/300953
首页 | 归档 | 分类 | 标签 | 关于 |
|
对于21世纪的人类,已经不满足于单核并行的模式;提高效率,增效降本才是我们向往的。程序设计中选择什么样的数据结构体是解决某个问题的关键。如果多线程使用到的数据结构体要满足并发,则涉及到数据的线程安全问题,一种解决办法是选择单独的互斥元或外部锁来使数据结构体在某一时间段独占,且释放后没有残留。另一种就是设计可以多线程同时访问的数据结构体。明显,后者在大部分场景是效率较高的。
腾讯云云监控团队对于自定义监控的场景没有一个适应现代化的上报组件,历史上例如 monitor、巴拉多、哈勃等监控系统,由于年代比较久远,只支持单维度上报、无法支持多维度的场景或改造困难,以及对于业界比较流行的统计方式(histogram、summary)无法支持,性能相对较差,页面老旧,无法覆盖业务场景,因此迫切需要一个上报组件,在业务和监控中台之间做一个连接。采集业务的指标数据进行处理、聚合后上报到监控中台。
因此我们云监控的自定义指标监控的路径为:TCCM SDK -> TCCM Agent -> 监控中台
。TCCM 全称为:tencent cloud - cloud monitor,即腾讯云云监控。在 TCCM SDK 的整体设计中,业务通过调用 SDK 提供的 API 接口,将自己的监控数据写入 SDK 内部的线程安全队列,然后由与 SDK 内部的线程去消费数据并发送给 TCCM Agent。如下图:
如上图是我们第一版本的 tccm 框架,首先进行具体的介绍,业务方会多线程调用我们 Tccm SDK 提供的接口,申请内存,填充数据;然后将数据写入线程安全队列。SDK内部会有 N 个线程读取数据并处理数据,最后批量发送数据。
相信我们很容易可以发现问题,一是内存空间可以是复用的,二是线程安全队列的读取线程可以一次读取所有数据然后批量发送。
一个类应该只负责一个职责,也就是说,一个类中应该是一组相关性很高的函数以及数据的封装
由 Bertrand Meyer(勃兰特.梅耶)在1988年出版的《面向对象软件构造》。
一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。提倡一个类一旦开发完成,后续增加新的功能就不应该通过修改这个类来完成,而是通过继承,增加新的类。
为什么应该对修改关闭呢?因为一旦修改了某个类就有可能破坏系统原来的功能,就需要重新测试。但是也不是一定不能修改,如果在有条件的情况下及时重构,能够避免系统加速腐败
所有引用基类(父类)的地方必须能透明的使用其子类的对象。也就是说,一个软件系统中所有用到一个类的地方都替换成其子类,系统应该仍然可以正常工作。这个原则依赖面对对象的继承特性和多态特性。我们要做到面向抽象(接口)编程
malloc函数是一个我们经常使用的函数,如果不对会造成一些潜在的问题。下面就malloc函数的线程安全性和可重入性做一些分析。
我们知道一个函数要做到线程安全,需要解决多个线程调用函数时访问共享资源的冲突。而一个函数要做到可重入,需要不在函数内部使用静态或全局数据,不返回静态或全局数据,也不调用不可重入函数。
malloc函数线程安全但是不可重入的,因为malloc函数在用户空间要自己管理各进程共享的内存链表,由于有共享资源访问,本身会造成线程不安全。为了做到线程安全,需要加锁进行保护。同时这个锁必须是递归锁,因为如果当程序调用malloc函数时收到信号,在信号处理函数里再调用malloc函数,如果使用一般的锁就会造成死锁(信号处理函数中断了原程序的执行),所以要使用递归锁。
虽然使用递归锁能够保证malloc函数的线程安全性,但是不能保证它的可重入性。按上面的场景,程序调用malloc函数时收到信号,在信号处理函数里再调用malloc函数就可能破坏共享的内存链表等资源,因而是不可重入的。
至于malloc函数访问内核的共享数据结构可以正常的加锁保护,因为一个进程程调用malloc函数进入内核时,必须等到返回用户空间前夕才能执行信号处理函数,这时内核数据结构已经访问完成,内核锁已释放,所以不会有问题。
mmap是一种内存映射文件的方法,将一个文件或者其它对象映射到进程的虚拟地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址一一对应的关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享
如上,进程的虚拟内存地址空间,由多个虚拟内存区域构成。比如 text数据段(代码段)、堆、栈 等都是一个独立的虚拟内存区域。Linux 内核使用 vm_area_struct
结构来表示一个独立的虚拟内存区域,各个 vm_area_struct
结构体使用链表或者树形结构链接