在 TCP 服务器中使用 pthread_create 时出现错误 11

Posted

技术标签:

【中文标题】在 TCP 服务器中使用 pthread_create 时出现错误 11【英文标题】:Error 11 when using pthread_create in TCP server 【发布时间】:2021-12-24 10:18:13 【问题描述】:

我有一个 C 应用程序,它侦听 TCP 端口并在每次接受新连接时创建一个新线程。它最初工作正常,但过了一会儿我开始从 pthread_create 收到错误代码 11。

线程函数体内没有与线程相关的函数调用,日志显示每个'in'都有一个匹配的'out'。

当它失败时,我直接调用线程函数,它在主线程上无限期地工作,所以我似乎不太可能用完函数内的资源。关于导致错误 11 的原因以及如何修复它的任何建议?

这是线程函数:

void * tcp_process_message (void * arg) 
    MESSAGE_BUFFER * bp = (MESSAGE_BUFFER *) arg;
    USER_LOG (UL_INFO, "tpm in %d", bp - buffers);
    ...
    USER_LOG (UL_INFO, "tpm out %d", bp - buffers);

这是创建线程的部分:一旦创建新线程,就没有其他代码与它交互了。

while(!cancel)
    connfd = accept(listenfd, (struct sockaddr *) &from_addr, &fromsize); 
    if (!cancel) 
        MESSAGE_BUFFER * bp = allocate_message ();
        if (bp == NULL) 
            USER_LOG (UL_ERROR, "%s", "allocate_message failed");
            close(connfd);
        
        else 
            bp->connfd = connfd;
            strcpy (bp->ip_addr, inet_ntoa(from_addr.sin_addr));
            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);
            
        
    

【问题讨论】:

*“它最初工作正常,但过了一段时间我开始收到错误代码” - 收紧并给出正确的minimal reproducible example。据我们所知,您没有正确等待/销毁线程,并且这些资源是有限的。你的结果是EAGAIN,用线程来说这意味着你的线程资源不足。服务队列的可能性很大,而且专用线程池无论如何都更适合您的用例。 使用strerror(err) 将错误号转换为有意义的字符串。 【参考方案1】:

创建线程时,即使线程函数退出,线程资源仍然存在。

某些代码必须使用pthread_join(the_thread); 等待线程,或者,它必须分离线程并在其函数退出时让它死掉:pthread_detach(the_thread);

如果不这样做,线程会留在系统中,系统很快就会耗尽资源,无法再创建新线程。

【讨论】:

啊,我不知道:我假设函数退出时线程资源被释放。这看起来像我的问题。我会尝试添加一个 pthread_detach。

以上是关于在 TCP 服务器中使用 pthread_create 时出现错误 11的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VB.NET 中检查 TCP 服务器(套接字)与 TCP 客户端的连接状态

如何在 C++/QT 中使用 TCP 服务器套接字创建 Http 服务器

为啥在 TCP 中使用 bind()?为啥它只用在服务器端而不用在客户端?

在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?

使用 IOCP 的 TCP/IP 服务器。接收缓冲区中的偶尔数据损坏

如何使用“C”在 Windows 中找到空闲的 TCP 端口