实现线程库有两种方式:
第一种,在用户级实现,这样做可以尽可能少地依赖于内核的支持.POSIX库就是这种情况.
第二种,在内核级实现,这样对用户程序的迁移/兼容比较容易.
OS/2,Win32是第二种.
进程结构
系统唯一知道的事情是进程结构.
LWP(轻量级进程)LWP可以被认为是个可以执行代码的虚拟cpu。可以独立地被内核调度,可以独立地执行系统调用.
通常,进程由内存,cpu寄存器状态,某些系统状态(文件描述符,usrID,工作目录等)组成.
当进程间发生环境切换时,内核会保存进程结构里的寄存器,虚存指针,载入另一个进程的cpu寄存器,然后继续.
当线程间发生环境切换时,大致工作如上,但存储影射和当前进程指针保持不变.
这个概念就是:你有单个程序,保存在1个地址空间,有许多虚拟的CPUs并发地跑着程序的不同部分.
LWPs是进程结构的一部分。
就像线程共享进程的结构一样,线程也同样共享大部分操作系统的状态。每个线程共享相同的打开文件,工作目录,Usr Id等。
系统调用多任务操作系统允许用户程序利用系统调用这样一种方式从系统内核获得信息或服务。
系统调用分这么几步:
1.进程陷入内核
2.trap处理器运行在内核态,保存寄存器
3.将堆栈指针指向内核堆栈的进程结构
4.内核运行系统调用
5.内核将所得数据放到用户空间的指定结构
6.内核改变受影响的进程结构值
7.进程返回用户模式,恢复寄存器和堆栈指针
当然,系统调用并不总是成功,不成功会返回失败值。系统调用也可能会被信号打断。
signal(信号)signal是unix的一种机制,用以获取一个程序中的异步的行为。
当1个进程进行系统调用时,以下事件发生:
1. 程序调用sigaction(),声明某个函数foo()为信号SIGUSR1的handler。
2. 程序调用sigprocmask(),告诉内核可接受的信号SIGUSR1
3. 程序启动,做你让它做的事情
4. 某个进程发送SIGUSR1给你的进程,你的进程停下手中的事情
5. 跑handler--foo()
6. 返回,继续做手中的事情。好像什么事都没发生一样。
阅读(882) | 评论(0) | 转发(0) |