在LInux中,线程就是轻量级的进程
线程和进程的关系
- 轻量级进程(light-weight process), 也有PCB, 创建线程使用的底层函数和进程一样都是clone
- 从内核里看进程和线程是一样的, 都有各自不同的PCB, 但是PCB中指向内存资源的三级页表是相同的
- 进程可以蜕变成线程
- 线程就是寄存器和栈
- 在Linux下, 线程就是最小的执行(CPU调度)单位, 进程是最小的资源分配单位
clone:
在创建一个进程时用fork, 创建一个线程时用creat, 他们都调用底层的函数clone, 可以克隆PCB,0~3G的用户空间,操作系统并没有为用户提供直接创建线程的系统调用接口, 因此大佬们封装了一套线程库实现线程控制,因此我们创建的线程也叫用户态线程
在内核中vfork创建一个子进程共用同一个虚拟地址空间, 怕出现调用栈混乱, 因此子进程运行完毕或程序替换后父进程才开始运行
多线程pcb使用同一个虚拟地址空间: 实现同时运行而不出现调用栈混乱----为每个线程在虚拟地址空间中单独分配一块空间
线程间共享资源
- .文件描述符表
- 每种信号的处理方式, 没有共享信号屏蔽字, 每个线程内部有自己独立的信号屏蔽字
- 当前工作目录
- 用户ID和组ID
- 内存地址空间
线程间非共享资源
- 线程id
- 处理器现场和栈指针(内核栈)
- 独立的栈空间(用户空间栈)
- errno变量
- 信号屏蔽字
- 调度优先级
线程的优点和缺点
优点:
提高程序的并发性
开销小, 不用重新分配内存
通信和共享数据方便
线程的执行粒度更细
缺点:
线程不稳定(库函数实现)
线程调试比较困难(gdb支持不好)
线程无法使用UNIX经典事件,例如信号
线程之间缺乏访问控制—系统调用(exit),
异常针对整个进程, 健壮性低