Yuerer's Blog

钰儿的Blog

前言

本节主要是讲 网络编程中, 常用的I/O 多路复用. 全文大概分为以下几点.

  1. 为什么需要I/O多路复用?
  2. I/O多路复用的使用场景?
  3. 为什么都是与非阻塞I/O进行搭配, 而不是与阻塞I/O进行搭配呢?
  4. select 的 优缺点 及 内核实现
  5. poll 的 优缺点 及 内核实现
  6. epoll 的 优缺点 及 内核实现
阅读全文 »

这是 Linux 系统编程系列 中的第一篇, 在这个系列里面, 我想以这么个顺序来讲述每一篇的内容, 先是快速简单地了解一下 常见的使用方法, 即API如何使用, 接着再深入其中, 了解内核为API提供的帮助, 大致是 C标准库 → 系统调用 这么个学习路线.

时间的定义

首先要记住 计算机的起始时间 为 (格林威治时间)1970年1月1日0点, 被称作 GMT时间 是时区时间, 不过它是根据地球公转和自转来计算的, 不是特别准确. 在计算机世界中, 往往被称作 UTC时间, 它是以原子钟来计算时间, 简单来说就是 UTC时间 比 GMT时间要准确, 同时两个时间又恰好没有时差, 但是UTC时间又不是时区时间, 因此容易被人弄混.

阅读全文 »

Loki Allocator 有三个类 这玩意对比起 pool allocator 的优点就在于 它有把内存还给系统

但是它作为一个 内存分配器 却在里面使用了 vector 作为容器… 按道理来说 应该在其内部实现一个简易版的 vector 才不会那么奇怪 但也没所谓 只是 先用了一次标准库的分配器 后续使用容器的时候 就可以用 Loki 分配器了.

  • Chunk
  • FixedAllocator
  • SmallObjAllocator

Chunk 解剖

Chunk 是整个分配器的最底层 里面主要是三个 成员变量

1
2
3
4
5
6
// 指向内存块
unsigned char * pData_;
// 目前可用区块的第一块的索引
unsigned char firstAvailableBlock_;
// 有多少块可用
unsigned char blocksAvailable_;

Chunk 的几个关键函数 已进行 剪裁 和 修改

Chunk 分配

分配流程很简单 就是 申请了内存以后 将每个小区块的第一个字节设置为索引 排好号

取的流程:

  1. 从 当前可用区块的第一块索引中取 得当前可用区块
  2. 当前可用区块会被返回
  3. 被返回的可用区块中的索引 被设置到 当前可用区块索引去(这样下一次就会使用到它)
  4. 可用区块数目 - 1
阅读全文 »

为什么要实现内存池?

一方面 是为了减少 调用 malloc() 的次数(尽管 malloc() 不慢) 但是调多了 会产生(外碎片)

另一方面 是因为 每次用 malloc() 分配到的内存 是要交税的 就是上一节中讲的 cookie 里面记录着 这一块内存的大小信息(内碎片) 特别是在频繁申请小内存的时候尤为明显

最终 pool_allocator 版本

具体代码可见 Memory_Pool

原理可见 C++ 内存管理 之 STL内存分配实现原理

阅读全文 »

本文主要讲讲 GNU-C++ 4.9 下的扩展内存分配器

首先 GNU-C++ 4.9 有 7 个扩展的内存分配器

  • new_allocator
  • malloc_allocator
  • pool_allocator
  • __mt_alloc
  • array_allocator
  • debug_allocator
  • bitmap_allocator

主要看看 pool_allocator array_allocator bitmap_allocator

以下源码都可在 .../ext/*.h 下找到 我将其进行了适当的 删减和修改

__gnu_cxx::new_allocator

直接用 ::operator new::operator delete 实现出来的 好处是 可以被重载 没啥特色

1
2
3
4
5
6
7
8
9
10
template<typename _Tp>
class new_allocator {
public:
pointer allocate(size_type __n, const void* = 0) {
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
void deallocate(pointer __p, size_type) {
::operator delete(__p);
}
};
阅读全文 »

本文主要讲的是 各个C++版本 中的STL标准库中的默认内存分配器 的 各种实现

VC6 标准分配器实现

VC6 它什么内存管理都没做 直接调用的 operator newoperator new 内部实际上 调用的就是 malloc

此外 VC6 下 是以元素为单位 比如 int 的话 他就会分配 512 ints 如果是 double 则会分配 512 doubles

GNU-C++ 2.9 以字节为单位 GNU-C++ 4.9 以元素为单位 在 G2.9 中的容器默认分配器 被移到了 pool_allocator

注意 G2.9 的标准分配器 和 容器默认分配器 不一样噢!

GNU-C++ 2.9 标准分配器实现

std::allocator 标准分配器 也是什么都没做

但是 G2.9 容器使用的分配器 不是上面的那个 std::allocator 而是 std::alloc

阅读全文 »

为什么要叫原生版本?

因为我觉得这一块是 C++ 自带的表达式 表达式里面 去调用 C语言的 CRT 库中的 mallocfree 但这篇 只讲自带的表达式 而不去深究 CRT 中的内存分配函数 所以只叫原生版本

常见的内存分配

分配释放类属可否重载
malloc()free()C 函数
newdeleteC++ 表达式
::operator new()::operator delete()C++ 函数
allocator::allocate()allocator::deallocate()C++ 标准库自由设计搭配的容器

使用示例

其中 ::operator new() 和 ::operator delete() 调用了 malloc() 和 free()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    void *p1 = malloc(512);
free(p1);

complex<int> *p2 = new complex<int>;
delete p2;

void *p3 = ::operator new(512);
::operator delete(p3);

#ifdef _MSC_VER
// 属于 non-static 要先实例化object再调用
int *p4 = allocator<int>().allocate(3, (int*)0);
allocator<int>().deallocate(p4, 3);
#endif

#ifdef __GUNC__
// 早期 GNU-C++ 2.9 版本
// void *p4 = alloc::allocate(512);
// alloc::deallocate(p4, 512);
// alloc 换名字了
void *p5 = __gnu_cxx::__pool_alloc<int>().allocate(9);
__gnu_cxx::__pool_alloc<int>().deallocate((int*)p5, 9);
// 4.9 版本之后
void *p4 = allocator<int>().allocate(7);
allocator<int>().deallocate((int*)p4, 7);

#endif
阅读全文 »

VSCode 近期推出了 Remote-SSH 这个工具 使得 Linux开发者 能够在本地(Windows 机)上直接对开发机源码进行修改 简直拯救了一大批人啊… 但是却没有提到 如何离线安装 因此本文可能是最早 尝试离线安装的教程

离线安装

  1. 本地上下载好 VSCode Insiders
  2. 安装 Remote-SSH 插件
阅读全文 »

首先 IPv4 资源是非常稀少的 大约只有 43亿 而且这还是包括了私有IP地址段的 其次 IP地址分为了五类 其中 D类地址没有主机标识 常被用于广播 E类被保留 我们不去管它

那就只剩下了 A B C 三类 问题是 A类和B类的链路允许非常多的计算机连接 实际网络架构上 根本用不到那么多 这就造成了IPv4的浪费 这个时候 子网掩码出现了

子网掩码的意义

将 A B C类网络进行更细的划分 避免浪费 IPv4地址 也可以把小的网络归并成大的网络即超网

子网掩码的理解

假设有一个财主 他有256间房子 房子的编号是 0~255 然后它的房子都在192.168.0这一条街上 现在他有8个儿子 要分家 则相当于 每个人都分得32间房子

阅读全文 »

在天朝这么久 你曾为网络状况不佳而烦恼过吗? 平时使用的 Shadowsocks 是怎么实现?
这篇讲的就是 如何用 Golang 实现一个最为基础的 Shdowsocks 的功能的软件 我将本文实现的软件取名叫 GoSocksProxy

老规矩先介绍一遍 什么是 GoSocksProxy? 它是怎么来的?

GoSocksProxy

一个 Golang 所写的网络混淆代理 是学习 SOCKS5 协议时的副产品 为此还做了一张图

GoSocksProxy

阅读全文 »
0%