TCP服务器调用pthread_create返回错误码11的问题排查求助
问题原因分析
pthread_create返回错误码11对应Linux系统下的EAGAIN错误,核心原因是系统无法为新线程分配资源,结合你提供的代码场景,99%的概率是退出的线程资源未被回收:
- Linux下默认创建的线程是
joinable状态,这类线程执行结束退出后,操作系统不会自动释放其占用的内核资源(包括线程描述符、栈空间配额等),必须主动调用pthread_join回收,或者提前将线程设置为detached状态由系统自动回收。 - 你代码中创建线程后没有做任何回收处理,每处理一个连接就会残留一份线程资源,运行一段时间后进程的可用线程配额被占满,再调用pthread_create就会返回EAGAIN错误。
- 你看到的
tpm out日志只能证明线程函数的业务逻辑执行完毕,不代表系统层面的线程资源已经释放,和这个问题不冲突。
修复方案
针对你的短连接处理场景,最简单的修复方式是将线程设置为detached状态,可选两种实现方式:
方案1:创建线程后立即调用pthread_detach
只需要在pthread_create成功后加一行代码即可:
int err = pthread_create (&tid, NULL, &tcp_process_message, (void *) bp); if (err) { USER_LOG (UL_ERROR, "thread create failed (%d)", err); tcp_process_message ((void *) bp); } else { // 新增这行,标记线程为分离状态,退出时自动回收资源 pthread_detach(tid); }
方案2:初始化线程属性时设置为分离状态
适合批量创建线程的场景,提前配置好属性复用:
// 循环外初始化线程属性 pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); while(!cancel){ // ...原有逻辑 int err = pthread_create (&tid, &thread_attr, &tcp_process_message, (void *) bp); // ...原有逻辑 } // 程序退出前销毁属性对象 pthread_attr_destroy(&thread_attr);
验证方法
修复后可以执行ps -T p <你的进程PID>查看进程的线程数变化,正常情况下线程数会随连接处理完成回落,不会持续上涨到上限。
内容的提问来源于stack exchange,提问作者JavaLatte
相关产品推荐
相关产品推荐

