Linux下的用户级多线程库 Fthread
1.Fthread简介 Linux下的用户级线程。不调用内核的任何线程功能。仅包含一句汇编,程序长度百行左右。非常简化的线程库。 2.线程简单说明 线程的特征 (1)并发执行。需要独立的程序计数器 (2)独立性。独立性弱于进程,可以互相影响。但是也有一定的独立性。因此必须为每个进程维护专属于线程的资源。 (3)协作性。线程不完全独立,都能使用进程的全局量、打开文件表等等资源。 (4)由协作性所引发的,同步问题。 教材所提及的线程包括的项:程序计数器、堆栈、寄存器集、子线程、状态。 Fthread对这些项做了简化,去掉了子线程和状态两项。 在线程间来回切换实际上就是对每个线程专属资源的切换,简单描述:开始线程1正在执行,在某一时刻线程切换信号产生,调度程序被唤醒,保存当前线程的专属资源,选择下一个执行的线程,并恢复其程序计数器、堆栈指针、相关寄存器值。线程即投入运行。 3.线程的专属资源 程序计数器:在32位机中即为EIP寄存器,包含下一条指令的地址。 堆栈与寄存器:与函数调用、局部变量等有关。 一个典型的Linux下进程内存分布见下图:(摘自《深入理解计算机系统》) 说明: (1)不同于DOS等16位操作系统,Linux使用32位的虚拟地址空间。在操作系统课也学过,每个进程都独立地拥有4GB的虚拟内存空间。互相不影响。在这些系统中,指针变量是32位的,记录32位的地址值。不需要像在16位系统中一样通过段偏移寻址和DOS特有的near far限定符来访问内存。 (2)Linux下的进程,其内存模型是分段的,各个段有自己的属性,比如只读可写等等。大体分为代码文本段、数据段和堆栈段,以及一些系统保留区域和禁止访问的区域,比如0地址。所有的程序代码指令都存于代码段中,数据段存储全局变量与静态变量。又可细分出BSS未初始化的数据与已初始化的数据、常量区等等。Malloc所分配的空间位于数据段中,称为heap堆,是由低地址空间往高地址空间增长的。 非法访问了或者企图改写禁止的区域,将会产生一个段错误信号,SIGSEGV。这是指针编程中常出的错误。在Windows下通常表现为一个非法操作。举个简单的例子 main() { int *p=0; *p=32; } 试图访问0地址(NULL指针)引发段错误。 运用gdb调试器有助于发现这种错误。在Windows下也有gcc系列工具,Devcpp开发环境就用的是gcc编译器。在windows下同样能运用gdb发现和改正错误。 (3)函数调用和访问局部变量都需要用到堆栈(Stack)。局部变量空间分配在栈里,函数调用记录也存储在栈里。一些函数调用参数等也存在栈里。 堆栈是一种LIFO后进先出的数据结构。栈由地址高空间往地址低空间向下增长。每当有数据进栈的时候,栈顶指针往下移,数据进栈。出栈时,栈顶指针往上移,数据出栈。 (4)与堆栈相关的寄存器: ESP寄存器:栈顶指针。 EBP寄存器:基址寄存器。主要用于访问局部变量和分隔函数调用记录 以 void holdtest() { int a = 3; } 为例。调用该函数过后,堆栈的分布如下: 高地址 ———————— 返回地址 ———————— 原来的EBP值 <===========EBP的值 ———————— a ————————<===========ESP的值 低地址 a=3这句赋值语句,在内部实际上是这样一句汇编指令来实现的 MOV [...]
Tags: 多线程, 技术, 操作系统Posted in TTTech | 1 Comment »
