6

我在两个正在运行的系统上有一些代码,kernel 2.4.20并且kernel 2.4.38. 他们都有gcc 3.2.2并且glibc 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回收手柄?不幸的是我不能轻易改变内核。谢谢!

4

2 回答 2

4

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

任何一个

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

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

于 2012-07-05T13:17:36.610 回答
0

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

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

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

于 2012-07-06T11:47:58.393 回答