Linux 到现在还是没有线程呀?
来源:互联网 发布:java集合类详解和使用 编辑:程序博客网 时间:2024/04/30 06:15
http://www.adintr.com/article/blog/291
Linux中的多线程编程可使用pthread库。它的用法相对简单,不过对于其内部的工作原理,相关的技术资料并不多见。本文将讨论Linux下的线程模型及其工作原理。
我们先从pthread库的应用示例开始。我们通常所用的pthread库是GNU的C库glibc的一部分,通常你可以在Linux的/lib目录找到名为libpthread-x.x.so(x.x是版本号)的库,这就是多线程编程时所需要的pthread库。pthread可看作是POSIX thread的简写,POSIX对线程定义了一系列的标准,而glibc的pthread库则是对POSIX线程标准的实现。
下面的代码示例了一个简单的多线程程序:
#include <stdio.h>
void* threadFunc(void* arg)
{
printf("I am running in sub thread.\n");
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, threadFunc, NULL);
pthread_join(tid, NULL);
printf("I am running in main thread.\n");
return 0;
} 这个程序在链接时需要指定链接pthread库,否则将出现链接错误。这是因为pthread库相对标准C库libc.so来说,是一个单独的库,而libc则是默认被链接的。
下面的命令可顺利编译上面的代码,注意-l参数的使用,用来指定链接pthread库:
# gcc -o test thread.c –lpthread
上面的代码非常简单,仅仅是示例了使用pthread_create()函数创建了一个线程,对pthread库中函数的用法本文不作详细解释,不熟悉的读者可用man命令阅读相关文档。
glibc的pthread库是glibc利用Linux内核提供的系统调用来实现的线程库,对于2.4和2.6的内核,由于对线程的支持有所不同,其实现效率也有所差别。简言之,采用2.4及之前的内核的Linux系统通常使用较老的LinuxThreads项目提供的线程模型(当然这并不绝对,采用2.4内核的Redhat较早的试用了NPTL),而采用2.6内核的系统则通常采用新的NPTL项目提供的线程模型,后者的效率比前者要高得多,也更符合POSIX标准。
在Linux的内核中,进程是进行调度的最小单位,并没有真正的对线程的支持,可以说线程只是用户空间的概念,在内核中只能用进程来实现线程。一个进程的多个线程在内核中只是多个特殊的进程,它们虽然有各自的进程描述结构,却共享同一个代码上下文。在Linux上,这样的进程称为轻量级进程(Light weight process)。
同时,Linux内核提供了clone()系统调用,用来创建进程的一个拷贝,这个拷贝与被拷贝的进程共享相同的地址空间。LinuxThreads 项目正是使用这个调用来完全在用户空间模拟对线程的支持。这个任务在当时内核支持不够的条件下,具体的实现非常复杂。由于内核并没有线程组的概念,LinuxThreads模型只能在pthread库中,对每个进程下的线程组都增加一个额外的线程来进行管理,这就是LinuxThreads模型中著名的管理线程(Manager Thread)。这个管理进程负责对管理同一进程下的其他线程的创建、退出,资源的分配和回收,及线程切换等,非常复杂,开销也很大,而且一旦管理线程被杀死,其他线程都不能正确回收。另外,由于当时内核中缺乏对线程同步操作的支持,因此pthread库中的互斥量mutex等只能采用信号来实现,效率非常低。LinuxThreads模型在某些方面也不符合POSIX标准,比如用它在同一进程中创建的线程,都有自己唯一的进程ID,而不是同一个ID,而且接收信号的时候也只能按线程接收。
正是由于LinuxThreads模型的这些问题,Redhat的一些开发人员发起了NPTL(Native POSIX Thread Library)项目,来改进pthread线程库的这些缺点。目前基于NPTL模型实现的pthread线程库已被多数2.6内核的Linux系统采用,你可以用下面的命令来查看所使用的线程模型是NPTL还是LinuxThreads:
# getconf GNU_LIBPTHREAD_VERSION如果得到的结果是类似于“NPTL 2.5”则是使用NPTL,如果是“linuxthreads-0.10”则是LinuxThreads。
NPTL模型仍然采用clone()系统调用,在内核中还是通过进程来模拟线程,不过对LinuxThreads的一些主要缺点有很大的改进:
• 在内核中改进了clone()系统调用并引入新的exit_group()系统调用,优化了线程创建和结束,并且使得pthread库中不再需要管理线程,减少了很多开销。
• 在内核中引入新的线程同步原语Futex,并基于Futex来实现线程同步操作如互斥量、条件变量等,改进了原来LinuxThreads基于信号实现时的低效率。
• 符合POSIX标准:发送信号时能发送到同一进程下的所有线程;getpid()会为同一进程下的所有线程返回相同的进程ID。
- Linux 到现在还是没有线程呀?
- 现在没有IE还是不行的
- 从毕业到现在,还是单身,求解
- 百度不能访问了!成都到现在也没有恢复
- 从工作到现在,没有解决掉的问题:
- Linux到底有没有线程
- Linux到底有没有线程之我见
- 好久没有来csdn.net了,放下技术几年了,现在还是想找点感觉。为了在里面找回代码的回忆。
- 很长时间没有到csdn了,现在准备全面转向ASP.Net开发
- 解析到数据,但是还是没有 设置到适配器上的问题的解决。
- linux中查看现在使用的shell是ksh还是bash?以及怎样修改?
- 没有时间~~还是没有心情~~
- 继承现在没有理解的
- Linux I2C 驱动阅读的碰到的一些网上没有提到的东西 (现在有了)
- Linux I2C 驱动阅读的碰到的一些网上没有提到的东西 (现在有了)
- Linux:执行sudo apt-get install提示“现在没有可用的软件包
- 还是没有结果。。。。
- 还是没有标题
- flaot型与0比较问题
- 黑马程序员-- HTML 之设置颜色
- Android的进程,线程模型
- PRD
- sqldeveloper启动时报Unable to create an instance of the Java Virtual Machine Located at path: ..\..\jdk\
- Linux 到现在还是没有线程呀?
- UVA 10420 战利品列表
- 智能指针的一个bug
- java中各种时间格式的转化
- UVA 12337
- Qt中启动Uri
- 五款最好的免费同步软件
- Mybatis自动生成Mapper工具配置文件
- matlab安装详细说明--百度文库链接地址