pthread_create:无法分配内存

pthread_create:无法分配内存,c,linux,sockets,pthreads,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)

我编写了一个小型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\u request
运行正常。我还注意到在运行期间有许多与status
TIME\u WAIT
的连接(我为此使用了
netstat
)。那么哪里会出问题呢

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

要在线程完成执行时释放该线程,需要在该线程上调用
pthread\u join()
,或者可以将该线程设置为“分离”线程。分离的线程将在其结束执行时自动释放。你可以加上

pthread_detach(pthread_self());
转到
accept_request()
thread函数的开头,使其成为分离的线程

作为旁注,您在调用时有一个竞赛条件

 pthread_create(&newthread , NULL, &accept_request, &client_sock)
在这里,您将&client_sock传递给线程,这是一个局部变量。如果有两个客户端几乎同时连接到服务器,则最后一个客户端将覆盖
client\u sock
变量,并且两个线程将看到相同的文件描述符。例如,您可以这样做:

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

并确保您的accept_request线程
free()
是传入的参数。

,尽管这看起来并不好,即使从您发布的内容来看。您是否关闭连接并结束线程?这两个都是有限的资源,看起来您正在达到线程的极限……可能您最后没有释放线程的资源。您必须分离线程或加入它,这样线程退出后使用的所有内存都将被释放。在您的情况下,最好创建从开始分离的线程_request@user2224350当然可以,但是你会处理线程吗?即使退出/返回线程,线程也会消耗大量资源,直到从其他线程调用pthread_join(),或者在线程分离时自动释放。默认情况下,llinux上的线程具有8或10 MB的堆栈内存。因此,380个线程意味着您使用了近4GB的虚拟内存,这可能意味着您达到了一个极限。