pthread_create:无法分配内存

use*_*350 0 c sockets linux 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");
}
Run Code Online (Sandbox Code Playgroud)

大约380个成功连接后,出现错误消息

'pthread_create:无法分配内存'

每次新的连接尝试都会发生.我真的不知道这来自哪里,因为accept_request运行正常.我还注意到TIME_WAIT在运行期间有很多与状态的连接(我用过netstat这个).那么哪里出错了?

nos*_*nos 11

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

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

pthread_detach(pthread_self());
Run Code Online (Sandbox Code Playgroud)

到你的accept_request()线程函数的开始,使其成为一个分离的线程.

作为旁注,你有一个竞争条件

 pthread_create(&newthread , NULL, &accept_request, &client_sock)
Run Code Online (Sandbox Code Playgroud)

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

int *new_fd = malloc(sizeof *new_fd);
*new_fd = client_sock;
pthread_create(&newthread , NULL, &accept_request, new_fd)
Run Code Online (Sandbox Code Playgroud)

并确保你的accept_request线程free()是传入的参数.