Chinaunix首页 | 论坛 | 博客
  • 博客访问: 305008
  • 博文数量: 174
  • 博客积分: 3061
  • 博客等级: 中校
  • 技术积分: 1740
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 22:43
文章分类

全部博文(174)

文章存档

2011年(54)

2010年(14)

2009年(30)

2008年(26)

2007年(27)

2006年(23)

我的朋友

分类: LINUX

2006-06-01 17:51:48

    今天由于工作原因,需要在uclinux下使用linuxthread也就是libpthread以及进行信号投递处理。不过发现了很多困扰的因素,因为linuxthread的运行表现同pthread以及kernel有着千丝万缕的关系,在不同的平台上表现不同。


首先linuxthread到今天为止分为NTPL方式和普通方式(暂且这么称呼)。先说说这个普通方式吧。

linuxthread的实现已知遵照着一对一模式实现,也就是每个用户线程对应着一个kernel thread,同时由于linux kernel并不支持真正的kernel thread所以实际实现方式是以LWP轻量级进程实现,所以往往能够在多线程程序起动后发现竟然存在多个进程号。这样做的目的是将线程调度转化为linux kernel的进程调度,不需要另外独立实现线程调度。缺点是效率不够高,不过从我浏览的文章看随着kernel 的不断发展这个性能也在逐渐提高。总体来说,就是kernel调度LWP,LWP控制对应用户线程的方式来完成线程调度。

另外一点就是kernel中并没有线程组这个概念,因此对于同一个进程中的各个线程的上下文切换是用过linuxhtread库自身实现的一个用户线程来完成的,所以这个就是为什么ps -e看到的进程号实际上是所有线程数量+1,呵呵。

还有一个要说明的就是信号处理,由于实现方式实际是以LWP的方式实现,因此信号并不存在说投递个某个进程就可以投递给所有这个进程的线程这种说法,实际上如果通过pid方式进行投递只能投递给指定的线程。这里有一个说明,如果在threadproc中调用getpid你就能发现这个pid是不同于初试业绩是main函数运行线程的pid的。而threadporc pid以及main pid之外的那个pid就是linuxthread 库实现用来进行多线程管理context switching的pid。对于这种方式如果简单的通过killall -SIG appname的方式就会发现会有多个线程响应signal,如果你仅仅想让信号处理一次那么必须指定pid。

普通线程库中的线程由于共享了FS,VMS,SIGNAL等,因此任何一个线程对于文件以及信号的操作将立刻被其它线程看到,哪怕是main线程在没有起动其它线程之前做得操作。

特别需要提出的以嗲就是SIGUSR1,SIGUSR2这两个信号尽管在大部分目前使用的版本中已经被继续保留给用户使用了,但是在某些系统上比如我自己的uclunux+arm9系统上这个两个信号依然被linuxthread库保留,不过想来这个应该linuxthread库的实现问题,从我看到的一些资料来看,linuxthread在处理同步上大量的使用了信号处理机制,呵呵。


最后再说说NTPL。
1. 优化了clone系统调用的处理方式,已经不再需要由linuxthread库本身提供一个线程来负责上下文切换.
2. proc文件系统中仅仅显示main线程的信息,而不是所有LWP的信息.

至于如何在开发中使用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的调用(但是某些函数被取消了)

阅读(850) | 评论(1) | 转发(0) |
0

上一篇:05-31端午节

下一篇:2006-06-04 周日一天

给主人留下些什么吧!~~