网络编程中,对多个连接的并发处理是一个非常常见的需求。

要并发处理多个连接,最简单的思路就是使用OS线程,每个线程处理一个连接。这样每个控制流只处理一个连接上的数据收发,与大多数人的思维模式匹配,因此编写起来最容易,心智负担最低。但这种模式需要大量OS线程,消耗大量的系统资源,因此限制了这种模型的并发处理能力。

基于事件驱动编程则采用另一种思路,将连接的处理流程打乱,基于连接上发生的事件及存储的状态判断所需的处理逻辑。这种方案下,单个线程即可处理大量连接,效率极高。但由于这种模式下非线性的控制流,要做到正确编写,需要较高的水平。

基于“程序首先是给人看的,其次才是给机器看的”这一思路,心智负担较低的1:1模型必然更受开发人员欢迎,只是OS线程的性能损失阻止了这种方案的广泛应用。而Golang中协程的使用极大地降低了1:1模型的性能损失,因此得到了广泛的使用。

Golang提供的有栈协程虽然比OS线程便宜,但终究要付出额外的成本。Rust提供的async/.await异步却是“零成本抽象”的无栈协程,使用异步不需要使用堆分配或动态分发等。(异步本身是零成本的,但提供异步I/O的异步运行时可能有成本,所以性能低于其他方案也不是没有可能。)基于async/.await的Rust异步在高性能的同时,仍具有类似于1:1模型的线性控制流。

阅读全文 »

在多文件的Python程序编写中,使用 import 引用其他文件中的代码经常会出错。尤其是在涉及到包时,要达到目标往往需要反复调整,通过不断尝试来得到正确的结果。下面针对 Python 中的 import 机制进行一些探索。

阅读全文 »

为了从源代码构建一个全新的Linux系统,不可避免地涉及到大量的编译工作。而这里的编译,又不仅仅是“编译”,还隐含了“链接”等步骤。如果不仔细设计编译的过程,就容易在这个过程中发生链接错误,导致最终的产物无法正常工作。同时,gcc与glibc又涉及到相互依赖的“循环依赖”问题。

在这里,我们对交叉编译等概念进行介绍,并结合这些概念对LFS编译的思路进行分析。

阅读全文 »

Graphviz是一个开源的图可视化工具。它可将DOT语言描述的图结构渲染为SVG、PNG、PDF等图像。在图结构可视化分析、系统结构图可视化多个场景都可用。DOT语言作为文本形式表示的语言,可以轻松地纳入Git中进行版本管理。

Graphviz的使用上,既可以通过安装Graphviz软件进行本地渲染,也可以通过部分网站在线渲染。部分网站还能生成具有特定风格的图像。

下图展示了一个通过在线生成的Sketchy风格图结构。

阅读全文 »

最近实验室的服务器存储容量不够了,准备添加硬盘来进行扩容。服务器使用了 LVM 来存储 /home 目录的内容,而之前对 LVM 的了解较少,因此对 LVM 进行了一些了解。并通过虚拟机来模拟了硬盘的添加,实验了硬盘添加后进行扩容的操作。相关内容记录于此形成本文。

LVM 是一种可用在 Linux 内核的逻辑分卷管理器;可用于管理磁盘驱动器或其他类似的大容量存储设备。

LVM 利用 Linux 内核的 device-mapper 功能来实现存储系统的虚拟化(系统分区独立于底层硬件)。通过LVM,你可以实现存储空间的抽象化并在上面建立虚拟分区(virtual partitions),可以更简便地扩大和缩小分区,可以增删分区时无需担心某个硬盘上没有足够的连续空间,避免为正在使用的磁盘重新分区的麻烦、为调整分区而不得不移动其他分区的不便。

简单地说, LVM 可以将多个磁盘或磁盘分区组成一个逻辑硬盘(VG, Volume Group, 卷组),可以在这个逻辑硬盘上创建可动态调整的分区(LV, Logical Volume, 逻辑卷)。

通过这一层模拟,对存储的管理变得更加灵活。实现了 VG、LV的在线修改;无需考虑分区在硬盘上的位置,也不要求空间连续。提供了数据在硬盘间的迁移功能。此外,LVM还提供了诸如快照、镜像、缓存等功能。

而 LVM 的缺点在于需要额外的设置,且不支持在 Windows 系统下直接访问。另外,与使用 RAID 0 相似地,当一个磁盘损坏时会影响到整个卷组。

下面将简单地介绍 LVM 的基本组成,并对 LVM 的创建和动态扩容进行实验。

阅读全文 »

进行深度学习实验时,经常需要使用 GPU 服务器。在不同的实验中,对 CUDA 版本等要求各不相同。为了解决这一问题,可以通过 Docker 技术从而实现多套环境随意使用。但让所有用户都能够深入理解 Docker 可能较为困难,因此需要寻求其他方案。直觉的解决方法便是利用虚拟化技术给每位同学提供一个虚拟机。但鉴于虚拟化技术的性能损耗和 GPU 共用方面的困难,因此不太现实。

LXD 这一系统容器方案恰好可以实现这一目标。它基于容器技术,开销小,支持 GPU 共享,因此极为适合这一场景。通过这一技术还带来了一些额外的优势,如:用户所有操作均在容器中进行,避免了对宿主机系统的破坏;提供快照功能,可以在误操作导致容器损坏时恢复。

下面对搭建过程整理后汇总如下,作为记录。宿主系统为从 Ubuntu 14.04 LTS 持续升级达到的 Ubuntu 20.04 LTS ,中间经过大量安装软件等操作。若在全新安装的系统上出现无法定位包等情况,需要逐个解决。搭建过程中的踩坑过程略过,其中的操作可能有前后相关性,不能单独查看某一部分而直接进行复现。

阅读全文 »

近期对博客进行了重新整理。优化了提交记录,使得Git提交历史更加清晰。现将过程记录如下,以备后续查看。

阅读全文 »

现代编码模型

由统一码和通用字符集所构成的现代字符编码模型将字符编码的概念分为:有哪些字符、它们的编号、这些编号如何编码成一系列的“码元”(有限大小的数字)以及最后这些单元如何组成八位字节流。在Unicode Technical Report (UTR) #17中,现代编码模型分为5个层次。

阅读全文 »
0%