Linux多线程编程和Linux 2.6下的NPTL
在Linux 上,从内核角度而言,基本没有什么线程和进程的区别--大家都是进程。一个进程的多个线程只是多个特殊的进程他们虽然有各自的进程描述结构,却共享了同一 个代码上下文。在Linux上,这样的进程称为轻量级进程Light weight process。致此,就是关于线程的总体概念了,我们往往就在了解这个概念的情况下开始我们的多线程编程之旅。这对于多线程编程入门已经足够了,然而事 实上线程却要复杂的多。 首先多线程间的优先级调度,内存资源(栈)分配和信号投递就不是简单的共享同一个进程代码上下文所能所能解决的。其次,效率的问题:如何有效的使用多 cpu资源(2.4内核的多线程就无法使用多个cpu,一个进程的线程都被限制在同一个cpu上运行)。因此多线程库Pthread的实现并不是一件简单 的事情,它建立在特有的线程模型之上。
在Linux 2.4内核中,
Linux内核中使用了一个内核线程来处理用户态进程中的多个线程的上下文切换(线程切换)。由于内核中并没有什么线程组的概念,即一个进程的多个线程,
因此必须依靠在pthread库中实现一个额外的线程来管理其他用户线程(即用户程序生成的线程)的建立,退出,资源分配和回收以及线程的切换。由于当时
硬件并没有线程寄存器之类的冬冬来支持多线程,因此线程的切换性能和低下,并且需要引入复杂的机制在进程的栈中为各个线程划分出各自的栈数据所在位置,并
且在切换时进行栈数据拷贝。而最大的问题是内核中缺乏对线程间的同步机制的支持,因此pthread库不得不在底层依靠信号方式来实现同步,因此线程互斥
中的互斥量操作和条件量操作都转换为进程的信号操作。pthread的实现中充斥了极其复杂的信号操作。大家都知道信号本身是低速的通信方式,因此势必拖
慢了线程的实际性能。最后的问题就是信号处理,还有由于内核对线程的无知,必须由管理线程来接收信号后投递给相应的线程,一方面是效率低,另外一方面由于
信号产生的不确定性(比如读取一个文件的时候突然出错了),要准确投递所有的信号给正确的线程难以保证。
而在IA-32硬件结构中,出现了对线程寄存器的支持,因此Pthread的线程上下文切换速度有了很大提高。但是由于硬件限制局限,线程的数量必须小于8192个,反正我是觉得已经很多了。
于是从2.5代码开始Linux内核采用了NPTLNative Posix Thread Library)方式。NPTL的设计思想初稿可参考nptl-design.pdf(http://people.redhat.com/drepper/nptl-design.pdf)
首先在IA-32和x86-64位体系结构上能实现任意数量的线程数量。通过引入了TLS系统调用可以建立多个GDT全局描述符表,每个cpu维护一个描述符表,每个表项存放一个线程。
其次,clone系统调用优化了线程的建立和结束功能。也不再需要额外的调度线程的帮助就可以回收线程资源了。
其三,信号投递由内核完成,而不再需要额外的用户态管理线程的帮助,而严重错误信号之间结束整个进程。
其四,引入了新的退出系统调用exit_group()。原来的exit保留用于退出单个线程,exit_group用于退出整个进程。
其五, 新的exec调用会先结束到一个进程中的所有线程后再载入新程序的执行,而不是只结束调用的线程。
其六,所有线程的资源使用情况(cpu资源,内存资源)会报告给整个进程,而不再是只报告给初始化线程
其七,proc文件系统中只显示初始化线程的信息,而不再是所有线程的信息(上万个线程会把proc文件系统拖死)
其八, 支持线程脱离, 执行Pthread_join的线程不需要再执行no wait。
其九,由内核来维护初始化线程(变成内核线程了),并在proc文件系统中显示其状态,并维护直到所有线程退出来保证信号的投递。
其十,内核支持无限制的线程数量。
最后,允许pthread_join在子线程已死之后返回,即pthread_join的返回和子线程状态变成异步的了,提高了性能。
根据报告,NPTL中线程的启动和中止时间消耗只有Linuxthread的大约1/8,当线程数量急遽增加的时候,消耗时间的差异更加明显。
在线程间同步试验中,频繁进出临界区的时间消耗只有原来的一半。
更多的用户测试报告可以看 http://kerneltrap.org/node/422
至于如何在开发中使用NPTL可参考Migrating to Linux kernel 2.6 -- Part 5: Migrating apps to the 2.6 kernel and NPTL(http://linuxdevices.com/articles/AT6753699732.html)。需要做的事情有这么几件。
1:使用2.6的内核的系统平台
2:确定你的gcc支持NPTL
用# getconf GNU_LIBPTHREAD_VERSION命令来查看gcc的编译时的对多线程的支持方式
如果返回的是linuxthreads-0.10,说明你的gcc不支持NPTL
如果返回的是nptl-0.60这样的信息,说明你的gcc能用来编译新的NPTL
3:重新在这样的系统环境中编译你的程序,不需要改变程序中对pthread的调用(但是某些函数被取消了)
Linux多线程编程和Linux 2.6下的NPTL的更多相关文章
- Linux多线程编程阅读链接
1. 进程与线程的一个简单解释(阮一峰) 2. linux 多线程编程 3. Linux 的多线程编程的高效开发经验 (IBM)
- Linux多线程编程小结
Linux多线程编程小结 前一段时间由于开题的事情一直耽搁了我搞Linux的进度,搞的我之前学的东西都遗忘了,非常烦躁的说,如今抽个时间把之前所学的做个小节.文章内容主要总结于<Linux程序 ...
- Linux多线程编程初探
Linux线程介绍 进程与线程 典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情.有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程 ...
- ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程
为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...
- 【操作系统作业-lab4】 linux 多线程编程和调度器
linux多线程编程 参考:https://blog.csdn.net/weibo1230123/article/details/81410241 https://blog.csdn.net/skyr ...
- Linux多线程编程实例解析
Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...
- Linux多线程编程之详细分析
线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步.互斥,这些东西将在本文中介绍.我见到这样一道面试题: 是否熟悉POSIX多线程 ...
- Linux多线程编程(不限Linux)【转】
——本文一个例子展开,介绍Linux下面线程的操作.多线程的同步和互斥. 前言 线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步 ...
- Linux多线程编程(不限Linux)
前言 线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步.互斥,这些东西将在本文中介绍.我在某QQ群里见到这样一道面试题: 是否熟 ...
随机推荐
- Android开发之计算器(一)界面设计
计算器开发主要涉及到LinearLayout布局.EditText.Button的使用.为android入门基础内容. 打开android studio选择创建一个新的工程,应用程序的名称为Calcu ...
- Linux下iptables拦截Nginx的问题
环境:CentOS 6.4 X64,Nginx 1.5.3 问题:配置好Nginx后,加入了“iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT” ...
- vmware虚拟机上网:NAT搭建局域网
若是你不知道的情况下,可以编辑虚拟机网络配置,然后恢复默认,vmware会自动给你分配好ip,默认使用的是vmware8,下面的是使用默认的配置 看图 注意:子网的ip一定要在如上图所示的范围 适配器 ...
- [Java][RCP] 引入第三方jar包时出错: XXXcannot be found XXX
为什么会这样? 下面的博客有介绍,不在累赘 http://dengmin.iteye.com/blog/260585 这些博客貌似忘掉了一点,或者是我本地的Eclipse新建的项目Version不够高 ...
- Eclipse下jad反编译之“类文件查看器”不能处理给定的输入错误解决
Eclipse中的插件下载,安装和配置可以参考我的另一篇文章:MyEclipse反编译Class文件 下面重点讲解如何使用jad反编译 1.在DOS窗口中,到class所在目录,直接运行 >ja ...
- Ubuntu下Apache+php+mysql网站架设详解
目录 1 基础 2 安装 2.1 安装LAMP 2.2 图形化管理软件(可选) 2.2.1 安装webmin 2.2.2 安装phpmyadmin 3 配置文件路径 3.1 常用命令 3.2 配置ap ...
- const 的全面总结
可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类 ...
- 使用PHP计算上一个月的今天
一日,遇到一个问题,求上一个月的今天. 最开始我们使用 strtotime(“-1 month”) 函数求值,发现有一个问题,月长度不一样的月份的计算结果有误. 比如:2011-03-31,得到的结果 ...
- java之redis篇(spring-data-redis整合)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 20145120 《Java程序设计》第3周学习总结
20145120 <Java程序设计>第3周学习总结 教材学习内容总结 基本类型与类类型的概念 在java里使用数组和字符串 封装的概念 在java定义函数 重载的概念 static的概念 ...