[译]All About Thread-Local Storage
线程本地存储(TLS)提供了一种为不同线程分配不同对象的机制。它是GCC扩展__thread
、C11 _Thread_local
和C++11 thread_local
的通常实现,它们允许使用声明的名称来指代与当前线程相关的实体。本文将详细描述ELF平台上的线程本地存储,并触及其他相关话题,如:线程特定数据键和Windows/MacOS TLS。
线程本地存储(TLS)提供了一种为不同线程分配不同对象的机制。它是GCC扩展__thread
、C11 _Thread_local
和C++11 thread_local
的通常实现,它们允许使用声明的名称来指代与当前线程相关的实体。本文将详细描述ELF平台上的线程本地存储,并触及其他相关话题,如:线程特定数据键和Windows/MacOS TLS。
与进程近似,线程是允许应用程序并发执行多个任务的一种机制。如下图所示,一个进程可以包含多个线程。同一个程序的所有线程均会独立地执行相同的程序,且会共享统一份全局内存区域,包括初始化数据段(initialized data)、未初始化数据段(uninitialized data)以及堆内存段(heap segment)。
如下图所示,对于每个程序所分配的内存由很多部分组成,通常称之为“段”(segment)。
文本段(text)包括进程运行的程序机器语言指令。文本段具有只读属性,以防止进程通过错误指针意外修改自身指令。
初始化数据段(BSS)包括为未进行显式初始化的全局变量和静态变量。
对于初始化和未初始化数据段即用户初始化数据段(user-initialized data segment)和零初始化数据段(zero-initialized data segment)。
栈(stack)是一个动态增长和收缩的段,由栈帧(stack frames)组成。系统会为每个当前调用的函数分配一个栈帧。栈帧中存储了函数的局部变量(所谓自动变量)、实参和返回值。
堆(heap)是可在运行时(变量)动态进行内存分配的一块区域。堆顶端成为program break。
进程是资源(CPU、内存等)分配的基本单位,具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是独立运行和独立调度的基本单位(CPU上真正运行的是线程)。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
世界上一些真正的工匠精神,我们认为是理所当然的。其中之一就是 Linux 上常用的工具,比如ps
和ls
。尽管这些命令可能被认为是简单的,但当看清其本质时,却有更多的东西。这就是ELF或可执行和可链接格式的作用。一个用得很多的文件格式,但真正了解的人却寥寥无几。让我们通过这个介绍教程来了解一下吧!
软件定义的真正落地,还是在云计算平台里面的应用。2011年前后,OpenFlow被用于云计算平台中进行网络管理,并被广泛接受。在15年的时候,Gartner战略报告首次出现SDN(软件定义),SDN重新“定义”了传统的网络架构甚至通信产业。
Linux 内核支持多种 page size。
架构 | HugePage Size |
---|---|
arm64 | 4K, 2M and 1G (or 64K and 512M if one builds their own kernel with CONFIG_ARM64_64K_PAGES=y) |
x86 | 4K and 4M (2M in PAE mode,1GB if architecturally supported) |
amd64 | 2MB, 1GB |
ia64 | 4K, 8K, 64K, 256K, 1M, 4M, 16M, 256M |
ppc64 | 4K, 16M |
SystemTap 允许用户在不重新编译代码的情况下利用静态追踪、动态追踪工具,比如在任何地方动态插入printk,或者改变内核的关键数据结构(guru模式)。所有的操作都要以root
用户模式下进行。