我觉得线程可能是让人即爱又恨的东西。爱它的是:在很多时候它确实可以改善程序的结构,可以节省系统资源,甚至可以在一定程度上提高系统的效率。恨它的是:它很容易犯错,关于这一点我体会的是最深的,我们的系统就是由于线程造成了严重的问题。但是话又说回来了,我们也不能因噎废食,常言道“艺高人胆大”,我想只要我们有足够的知识和经验,线程会成为我们手里的一把利器。
我是在solaris上开发的,这里我想介绍一下solaris上的两种线程模型,从整体上描述一下该平台上线程开发的基本知识:
在solaris上有两种线程库,一种是符合POSIX标准的pthread库,一种是SUN自己的thread库,这里我主要针对POSIX标准进行描述。大家在用POSIX函数进行设置线程属性的时候,常常会遇到属性PTHREAD_SCOPE_PROCESS,那么用这种属性建立的线程叫做unbound线程,而采用属性PTHREAD_SCOPE_SYSTEM建立的线程叫做bound线程,那么unbound和bound线程到底有什么区别那?下面我将描述solaris上的两种线程模型,并从中给出答案。
two-level:solaris上的标准实现模型
740)this.width=740" border=undefined上面这个图中LWP是轻权进程的意识,这里你可以认为它就是CPU,用户空间的线程一旦获得了LWP,也就是说它获得了可执行能力,它可以随时被操作系统调度。
我们看这个图的左半部分,我们看到用户空间的thread和内核空间的LWP并不是一对一的关系,而是N对M的关系,那么由那个线程获得LWP,这个调度的完成是由线程库来完成的,而不需要内核的参与,也就是这种方式的线程上下文切换比较快,并且很明显这种方式更节省内核资源,solaris根据一定的策略提供一个LWP池,供上面更多的线程分享,这种线程就是所说的unbound线程。
看这个图的右半部分,我们可以看到用户空间的线程thread和LWP是one-to-one的对应关系,每一个线程都有一个永久的LWP为它服务,很明显这种方式的线程的实时调度性要好,但是这种线程的上下文切换需要KERNEL的参与,并且由于LWP本身是消耗操作系统资源的,因此这种方式要比上面的那种方式浪费资源,这种方式的线程就是所谓的bound线程。
one-level:solaris上可选实现模型
这种模型其实就是提供一致的线程和LWP的one-to-one对应关系,而没有thread和LWP的N对M的关系,很显然one-level模型要更耗系统资源,但是可能会提高程序的效率。
对于要重新编译的程序,可以加上编译选项-R /usr/lib/lwp来采用one-level模型,对于已经编译好的程序,那么在LD_LIBRARY_PATH环境变量设置加上/usr/lib/lwp即可。