pthread_create Linux 内核 2.4.20 和 2.4.36 的差异

pthread_create differences in linux kernel 2.4.20 and 2.4.36

本文关键字:Linux 内核 pthread create      更新时间:2023-10-16

我在运行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%xn", (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%xn", (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回收手柄?不幸的是,我无法轻松更改内核。谢谢!

如果您的观察是正确的,则仅存在两种可能的解决方案。

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

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

事实证明,

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

当我再次运行负载测试时,线程手柄到达0xFFFFF002然后翻转到0x1002并愉快地继续前进。

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