Sam前些天在提供一个库给别的公司时,因为不喜欢使用pthread_jion等函数,被人骂为垃圾程序。呵呵,之前因为在写多thread程序时,习惯让每个thread都为detach属性,这样他们就可以自我管理。而不需要再由别人回收资源。呵呵,不说这么多了,把POSIX
thread方面的东西记下来吧。
Linux下thread历史(Old
pthread与NPTL):
Linux创建之初,并不能真正支持thread. LinuxThreads
项目使用clone()这个系统调用实现对thread的模拟。在_clone本来的意图是创建一个可定义各种配置的对当前进程的拷贝。LinuxThreads项目则利用了这一点,配置了一个与调用进程拥有相同地址空间的拷贝,把它作为一个thread.
所以,常常有人说,linux下面没有进程线程之分,其实就是这个意思。但这个方法也有问题,尤其是在信号处理、调度和进程间同步原语方面都存在问题。另外,这个线程模型也不符合
POSIX 的要求。
如果要改进LinuxThread.
很明显,需要kernel层的支持。IBM和RedHat分别进行了研究,随着IBM的放弃,RedHat的Native POSIX
Thread Library(NPTL)就成唯一的解决方案了。这就是NPTL。
LinuxThreads
最初的设计相信相关进程之间的上下文切换速度很快,因此每个内核线程足以处理很多相关的用户级线程。这就导致了一对一
线程模型的革命。
LinuxThreads 设计细节的一些基本理念:
LinuxThreads 非常出名的一个特性就是管理线程(manager
thread)。管理线程可以满足以下要求:
系统必须能够响应终止信号并杀死整个进程。
以堆栈形式使用的内存回收必须在线程完成之后进行。因此,线程无法自行完成这个过程。
终止线程必须进行等待,这样它们才不会进入僵尸状态。
线程本地数据的回收需要对所有线程进行遍历;这必须由管理线程来进行。
如果主线程需要调用
pthread_exit(),那么这个线程就无法结束。主线程要进入睡眠状态,而管理线程的工作就是在所有线程都被杀死之后来唤醒这个主线程。
为了维护线程本地数据和内存,LinuxThreads 使用了进程地址空间的高位内存(就在堆栈地址之下)。
原语的同步是使用信号 来实现的。例如,线程会一直阻塞,直到被信号唤醒为止。
在克隆系统的最初设计之下,LinuxThreads 将每个线程都是作为一个具有惟一进程 ID 的进程实现的。
终止信号可以杀死所有的线程。LinuxThreads
接收到终止信号之后,管理线程就会使用相同的信号杀死所有其他