Linux是从什么时候开始支持线程的.

几天前和同事吃饭,谈论到一个问题:linux从什么时候开始支持线程。他说linux中的线程出现的很晚,直到2.2.x才有。

我觉得不对啊,怎么会那么晚。然后它用手机搜索了一下,linux对POSIX线程库的支持确实很晚,直到2.6.x才有。

但我觉得POSIX线程库只不过是用户空间用来创建线程的接口,并不能证明那么晚linux才支持线程。

后来用PC的时候搜索了一下,在The Linux Document Project的官方网站找到了答案:

http://www.tldp.org/FAQ/Threads-FAQ/Support.html

Does Linux support threads?

Yes. As of 1.3.56, Linux has supported kernel-space multithreading. There also have been user-space thread libraries around as early as 1.0.9. There is on-going effort to refine and make the kernel more reentrant. With the introduction of 2.1.x, the memory space is being revised so that the kernel can access the user memory more quickly.

问: Linux支持线程吗?

答: 是的,自从1.3.56开始,Linux就开始支持内核空间中的多线程了。早到1.0.9,就已经有了用户空间的线程库。

/////

这里有个比较混淆的概念:内核线程, 内核态支持多线程。

内核态支持多线持指的是在内核空间支持线程的调度,创建,销毁等操作。

内核线程则是另外一个概念,它和一般task的最大区别是,描述内核线程的task_struct结构体中的内存描述符mm_struct是NULL。具体参考经典书:linux kernel development. 我另一篇贴子也有写到: http://blog.ykyi.net/2012/06/%E5%86%85%E6%A0%B8%E7%BA%BF%E7%A8%8B%E6%98%AF%E4%BB%80%E4%B9%88%E4%B8%9C%E4%B8%9C-what-is-kernel-threads/ 是从Understand the linux kernel抄下来的。

    用线上机测试tcpcopy基本通过。支持旧模式,Advanced模式失败

    测试结果介绍:

     

    tcpcopy在编译期配置成使用NFQueue模式,用Raw Socket抓包。线上机的流量被成功复制并导向测试机。经改动的tcpd初期工作正常。

    改动版的tcpd(实际上是一个echo服务器)。测试机上的tcpd把收到的报文被打印到日志文件。但日志文件到6M+大小的时候,就停止打印。目前还没有查到原因,可能是改动后的tcpdBug。此时,tcpdump仍然抓到大量从线上机复制来的真实流量到达测试机。tcpcopy应该是工作正常的。

     

    tcpcopy被编译成使用libpcap抓包时不能在线上机上正常工作。tcpdump没有抓到预期从线上机复制到测试机的报文。原因是:线上机10.130.68.100上的真实流量从网络接口tunl0:0进入,从网络接口eth1发出。分析tcpd的日志发现,tcpd使用libpcap只拿到tunl0IP,没有发现tunl0:0IP。需要了解IP隧道,和libpcap库的相关知识,有可能解决这个问题。

     

    编译成使用Raw Socket抓包,和Advanced模式时,tcpcopy启动失败,错误日志显示Advanced模式只能使用libpcap库抓包。因此,只有在解决libpcap正确识别tunl0:0网络接口后,才能在线上机上运行tcpcopy

     

    预备知识:

    Tcpcopy可以编译成用libpcap抓包或者使用Raw Socket抓包。Libpcap库是tcpdump使用的抓包库,Raw Socket是操作系统内建的功能。

    官方文档建议用libpcap抓包,以获得更高性能和较低丢包率。

     

    Tcpcopy在编译期指定工作模式。tcpcopy目前有两种工作模式,一种使用IPQueue技术或者NFQueue技术。NFQueue技术是用来替代IPQueue技术的。我们目前使用的tlinux,内建了NFQueue内核模块,没有开启IPQueue模块。因为NFQueue是内建的即CONF_XXXXXX = y,而不是编译成模块,即CONF_XXXXX = m, 所以我们在环境中不需要使用modprobe 加载IPQueue或者NFQueue模块。忽略官方文档中提到的modprobe ip_queue

     

    测试步骤:

     

    使用NFQueue模式:

    线上机:10.130.68.100

    编译tcpcopy时指定使用NFQueue不要指定 –enable-pcap,则默认使用raw socket抓包。用pcap抓包时识别不到网络接口tunl0:0,而tunl0:0是真实流量的入口。

    # ./configure –enable-nfqueue

    #./make

    生成的tcpcopysrc/tcpcopy 目录下。

    运行tcpcopy命令,把流量复制到测试机:

    # ./tcpcopy -x 80-10.213.243.156

    测试机:10.213.243.156

    编译tcpcopy时同样指定–enable-nfqueue,不要指定–enable-pcap。然后运行intercept

    # ./intercept

     

    使用Advanced模式:

    因为暂时未能解决用libpcap识别到网络设备tunel0:0的问题,实际上Advanced模式暂时不能工作。根据以前的使用经验,用Advanced模式时需要注意两点:

    1. ./configure时指定 –enable-advaned –enable-pcap

    2. Advanced模式需要两台测试机,需要设成一条路由把复制后的真实流量导向测试机。需要更改默认路由:删掉当前的默认路由,新的默认路由从正确的网卡指向测试机2IP

    # route del default

    # route add default gw 10.213.243.156 dev eth1

    copyright blog.ykyi.net