linux 内核 2.4.20 和 2.4.36 中的 pthread_create 差异

Posted

技术标签:

【中文标题】linux 内核 2.4.20 和 2.4.36 中的 pthread_create 差异【英文标题】:pthread_create differences in linux kernel 2.4.20 and 2.4.36 【发布时间】:2012-07-05 12:31:05 【问题描述】:

我在运行kernel 2.4.20kernel 2.4.38 的两个系统上有一些代码。 他们都有gcc 3.2.2glibc 2.3.2

kernel 2.4.38 下,pthread_t 句柄没有被重用。在重负载测试下,一旦句柄达到0xFFFFFFFF,应用程序就会崩溃。

(我首先怀疑这是因为应用程序在 IT 使用网络端口扫描仪的部署中崩溃 - 创建线程是为了处理套接字连接)

这个简单的例子重现了这个问题:

void* ThreadProc(void* param)

    usleep(10000);
    printf(" Thread 0x%x\n", (unsigned int)pthread_self());
    usleep(10000);
    return NULL;


int main(int argc, char* argv[])

    pthread_t sThread;

    while(1)
    
      pthread_create(&sThread, NULL, ThreadProc, NULL); 
      printf("Created 0x%x\n", (unsigned int)sThread);  
      pthread_join(sThread, NULL);
    ;

    return 0;

2.4.20 下:

    Created 0x40838cc0
     Thread 0x40838cc0
    Created 0x40838cc0
     Thread 0x40838cc0
    Created 0x40838cc0
     Thread 0x40838cc0
...and on and on...

2.4.36 下:

    Created 0x4002
     Thread 0x4002
    Created 0x8002
     Thread 0x8002
    Created 0xc002
     Thread 0xc002
...keeps growing...

如何让kernel 2.4.36 回收句柄?不幸的是我不能轻易改变内核。 谢谢!

【问题讨论】:

向过去问好!我不认为在你的程序中依赖这样的内核行为是一个好主意,你应该修复你的程序。 @PlasmaHH:程序很好; pthread_join 应该释放所有线程资源。问题是,在那个特定的内核版本上,它显然没有。 @MikeSeymour:是什么让你这么想?对我来说,它看起来就像每次都分发一个不同的句柄,这非常好,即使前一个句柄已被释放。就像 a=malloc(5);free(a);a==malloc(5);一定不是真的。 @PlasmaHH:因为“在重负载测试下,一旦句柄达到 0xFFFFFFFF,应用程序就会崩溃”。这意味着句柄永远不会被重复使用。 @PlasmaHH:我不希望每次都使用相同的句柄,我只是希望它们在某个时候被重用。我的应用程序为每个传入的套接字创建一个新线程,因此它在几周后崩溃,因为它用完了线程句柄。顺便说一句,内核 2.6.35 也可以正常工作(如 2.4.20)。可惜我不能用! 【参考方案1】:

如果您的观察是正确的,那么只有两种可能的解决方案。

要么

    升级内核。这对您来说可能可行,也可能不可行。 在您的应用程序中回收线程。

即使内核行为不端,您也可以执行选项 2。您可以持有一个在不使用时保持在睡眠状态的线程池。线程池是一种广为人知的软件工程模式(参见http://en.wikipedia.org/wiki/Thread_pool_pattern)。这可能是更适合您的解决方案。

【讨论】:

总有3. back-port a fix from a future kernel version and rebuild your own kernel @Kevin A. Naudé:是的,我可能必须实现一个线程池。我仍然希望有人会知道内核 2.4.36 的简单解决方法。就像我说的,我不能轻易改变内核。 (包括建立我自己的) @Scott:如果你甚至不能构建一个修补过的内核来修复这个问题,那么你就没有修复内核的希望。似乎线程池可能是您最好的(也许是唯一的)选择。【参考方案2】:

原来我在负载测试中没有正确加入我的线程。

当我再次运行负载测试时,线程句柄达到 0xFFFFF002 然后滚动到 0x1002 并愉快地继续。

故事的寓意:确保你的线程是连接或分离的!

【讨论】:

以上是关于linux 内核 2.4.20 和 2.4.36 中的 pthread_create 差异的主要内容,如果未能解决你的问题,请参考以下文章

linux的简介

Linux编译内核显示进程列表

centos 6.0的内核版本是多少

Linux l 2.4.20-8 # 溢出

linux进程为啥有用户栈和内核栈,

Linux内核开发与Linux驱动开发有啥关系?