pthread_create Linux 内核 2.4.20 和 2.4.36 的差异
pthread_create differences in linux kernel 2.4.20 and 2.4.36
我在运行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%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
回收手柄?不幸的是,我无法轻松更改内核。谢谢!
如果您的观察是正确的,则仅存在两种可能的解决方案。
也
- 升级内核。这对您来说可能是可行的,也可能是不可行的。
- 回收应用程序中的线程。
选项 2 是即使内核行为不端也可以执行的操作。 您可以保留在不使用时保持休眠状态的线程池。 线程池是一种广为人知的软件工程模式(参见 http://en.wikipedia.org/wiki/Thread_pool_pattern)。 这对您来说可能是更好的解决方案。
事实证明,
我在负载测试中没有正确加入我的线程。
当我再次运行负载测试时,线程手柄到达0xFFFFF002然后翻转到0x1002并愉快地继续前进。
故事的寓意:确保你的线程是连接或分离的!
相关文章:
- 如何让ASan使用4.12.3 Linux内核?
- Linux 内核事件:timeval 或 timespec
- 在纯C++中实现 Linux 内核的 __is_constexpr (ICE_P) 宏
- 如何修复在 Linux 内核 SPI 驱动程序中始终无法验证的 SPI 驱动程序
- 使用 __builtin_expect() 或 Linux 内核时可能和不太可能时"very likely"多少
- C func签名Linux内核:Include/Linux/Sched.h
- 在C++中获取 Linux 内核模块的详细信息
- 清除Linux内核链接列表
- pthread_create Linux 内核 2.4.20 和 2.4.36 的差异
- Mac/IOS 是否使用与 Linux 内核相同的 sys/socket.h?
- linux内核.h文件中定义的宏
- 如何将 C/C++ 应用程序移植到旧版 Linux 内核版本
- 当多个高优先级线程在多个内核上运行时,Linux内核没有响应
- 如何定义几个源文件访问的Linux内核变量
- linux内核模块对c++异常的支持
- 在c++中使用来自linux内核头ioprio_h的ioprio_set()
- 不使用Inotify从Linux内核读取文件系统事件
- 哪个进程拥有给定的端口(Linux内核)
- 解析 Linux 内核文件时"Idle Service Error semantic-idle-summary-idle-function - Arithmetic error" cedet 语义错误
- 在32位linux内核上使用c++在堆上分配超过2GB的空间