2017-02-24 42 views
0

我写了一个小的TCP服务器,它创建用于每个传入连接一个新的线程:在pthread_create:无法分配存储器

while (server_running) 
{ 
    client_sock = accept(server_sock, 
        (struct sockaddr *)&client_name, 
        &client_name_len); 

    if(!server_running) 
    break; 
    if (client_sock == -1) 
    continue; 
    /* accept_request(client_sock); */ 
    if (pthread_create(&newthread , NULL, &accept_request, &client_sock) != 0) 
    perror("pthread_create"); 
} 

后约380全成连接,该错误消息

“在pthread_create:无法分配内存”

发生在每一个新的连接尝试。我真的不知道这是从哪里来的,因为accept_request正常运行。我还注意到,在运行过程中存在与状态TIME_WAIT许多连接(我用netstat此)。那么哪里可能出现问题?

+0

[MCVE],虽然这看起来并不甚至有点您张贴什么好。 – EOF

+2

你有没有关闭连接并结束线程?两者都是有限的资源,看起来你已经达到了线程的限制... – Kninnug

+2

也许你没有在最后释放线程的资源。您必须分离线程或将其加入,以便线程使用的所有内存在退出后都会释放。在你的情况下,它可能最好创建从头开始分离的线程。 –

回答

11

当你的线程退出,但它仍然在内存中徘徊。默认情况下,Linux上的线程消耗8或10MB的堆栈,因此使用380线程时,可能会使用近4GB的虚拟内存 - 这可能会对系统造成限制。

要在完成执行时处理一个线程,您需要在该线程上调用pthread_join(),或者可以使该线程成为“分离”线程。分离线程在结束执行时会自动处理。您可以添加

pthread_detach(pthread_self()); 

accept_request()线程函数的开始,使之分离线程。

作为一个侧面说明,你在电话会议上的竞争条件,以

pthread_create(&newthread , NULL, &accept_request, &client_sock) 

在这里,您传递& client_sock给线程,一个局部变量。如果你有2个客户端连接到你的服务器几乎在同一时间,最后一个将覆盖client_sock变量,你的线程2将看到相同的文件描述符。你可以例如而做到这一点:

int *new_fd = malloc(sizeof *new_fd); 
*new_fd = client_sock; 
pthread_create(&newthread , NULL, &accept_request, new_fd) 

,并确保您accept_request线程free()的参数中传递。