日期:2014-05-16  浏览次数:20686 次

linux 2.6进程与线程
1 >    线程和进程的差别
线程机制支持并发程序设计技术,在多处理器上能真正保证并行处理。而在linux实现线程很特别,linux把所有的线程都当作线程实现。
linux下线程看起来就像普通进程(只是该进程和其他进程共享资源,如地址空间)。上述机制与Microsoft windows或是Sun Solaris实现
差异很大。这些系统提供专门支持线程机制(轻量级进程)。

在现代操作系统中,进程支持多线程。进程是资源管理及分配的最小单元;而线程是程序执行的最小单元。一个进程的组成实体可以分为两大部分:线程集和资源集。进程中的线程是动态的对象,代表了进程指令的执行过程。资源,包括地址空间、打开的文件、用户信息等等,由进程内的线程共享。线程有自己的私有数据:程序计数器,栈空间以及寄存器。

现实中有很多需要并发处理的任务,如数据库的服务器端、网络服务器、大容量计算等。

如果采用多进程的方法,则有如下问题:
      1> fork一个子进程的消耗是很大的,fork是一个昂贵的系统调用。
      2> 各个进程拥有自己独立的地址空间,进程间的协作需要复杂的IPC技术,如消息传递和共享内存等。

线程推广了进程的概念,使一个进程可以包含多个活动(或者说执行序列等等)。多线程的优点和缺点实际上是对立统一的。使用线程的优点在于:

      1> 改进程序的实时响应能力;
      2> 更有效的使用多处理器,真正的并行(parallelism);
      3> 改进程序结构,具备多个控制流;
      4> 通讯方便,由于共享进程的代码和全局数据;
      5> 减少对系统资源的使用。对属于同一个进程的线程之间进行调度切换时不需要调用系统调用,因此将减少额外的消耗,往往一个进程可以启动上千个线程也没有什么问题。

缺点在于:
由于各线程共享进程的地址空间,因此可能会导致竞争,因此对某一块有多个线程要访问的数据需要一些同步技术。


2 >     线程的分类
2.1     内核线程
Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求)。内核需要多个执行流并行,为了防止可能的阻塞,多线程化是必要的。内核线程就是内核的分身,一个分身可以处理一件特定事情。Linux内核使用内核线程来将内核分成几个功能模块,像kswapd、kflushd等,这在处理异步事件如异步IO时特别有用。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。支持多线程的内核叫做多线程内核(Multi-Threads kernel )。内核线程的调度由内核负责,一个内核线程处于阻塞状态时不影响其他的内核线程,因为其是调度的基本单位。这与用户线程是不一样的。

2.2用户线程
用户线程在用户空间中实现,内核并没有直接对用户线程进程调度,内核的调度对象和传统进程一样,还是进程本身,内核并不知道用户线程的存在。

由于Linux内核没有轻量级进程(线程)的概念,因此不能独立的对用户线程进行调度,而是由一个线程运行库来组织线程的调度,其主要工作在于在各个线程的栈之间调度。如果一个进程中的某一个线程调用了一个阻塞的系统调用,整个进程就会被调度程序切换为等待状态,其他线程得不到运行的机会。因此linux使用了异步I/O机制。


3 >     内核线程
内核线程(thread)或叫守护进程(daemon),在操作系统中占据相当大的比例,当Linux操作系统启动以后,尤其是X window也启动以后,你可以用”ps -ef”命令查看系统中的进程,这时会发现很多以”d”结尾的进程名,确切说名称显示里面加 "[]"的,这些进程就是内核线程。系统的启动是从硬件->内核->用户态进程的,pid的分配是一个往前的循环的过程,所以随系统启动的内核线程的pid往往很小。

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:42 ?        00:00:01 /sbin/init
root         2     0  0 09:42 ?        00:00:00 [kthreadd]
root         3     2  0 09:42 ?        00:00:00 [migration/0]
root         4     2  0 09:42 ?        00:00:00 [ksoftirqd/0]
root         5     2  0 09:42 ?        00:00:00 [watchdog/0]
root         6     2  0 09:42 ?        00:00:00 [events/0]
root         7     2  0 09:42 ?        00:00:00 [khelper]
root        40     2  0 09:42 ?        00:00:00 [kblockd/0]
root        64     2  0 09:42 ?        00:00:00 [kseriod]
root       110     2  0 09:42 ?        00:00:00 [pdflush]
root       111     2  0 09:42 ?  &