pthread_create:无法分配内存

时间:2017-02-24 15:57:01

标签: c linux sockets pthreads

我写了一个小的tcp服务器,它为每个传入连接创建一个新线程:

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)。那么哪里出错了?

1 个答案:

答案 0 :(得分:11)

当你的线程退出时,它仍会在内存中挂起。默认情况下,linux上的一个线程占用8或10MB的堆栈,因此对于380个线程,您可能会使用近4GB的虚拟内存 - 这可能会对您的系统造成限制。

要在完成执行时释放一个线程,您需要在该线程上调用pthread_join(),或者您可以将该线程设置为'分离'线程。分离的线程在结束执行时将自动处理。你可以添加

pthread_detach(pthread_self());

accept_request()线程函数的开头,使其成为一个分离的线程。

作为旁注,你在

的召唤中遇到了竞争条件
 pthread_create(&newthread , NULL, &accept_request, &client_sock)

在这里,您将& client_sock传递给线程,一个局部变量。如果有两个客户端几乎同时连接到您的服务器,则最后一个客户端将覆盖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()是传入的参数。