为什么accept()系统调用在关闭上一个连接套接字之前不接受新连接

为什么accept()系统调用在关闭上一个连接套接字之前不接受新连接,c,linux,multithreading,C,Linux,Multithreading,我正在使用Pthreads在C中使用多线程设计一个multi-cleint web服务器,我有一个主线程在一个循环中进行侦听,当存在连接时,它会生成一个新线程,执行一个函数来服务,而主线程继续侦听连接 正如我从调试中注意到的,它一次只服务一个连接,Accept()系统调用正在等待该连接关闭,然后它将在队列中生成下一个连接 它的行为就像是一个单线程web服务器 void *ServeThread(void *param) { int tsk; tsk = (int)para

我正在使用Pthreads在C中使用多线程设计一个multi-cleint web服务器,我有一个主线程在一个循环中进行侦听,当存在连接时,它会生成一个新线程,执行一个函数来服务,而主线程继续侦听连接

正如我从调试中注意到的,它一次只服务一个连接,Accept()系统调用正在等待该连接关闭,然后它将在队列中生成下一个连接

它的行为就像是一个单线程web服务器

    void *ServeThread(void *param)
{    int tsk;
     tsk = (int)param;

    /* here im serving the connection (tsk), and then close it */
}

void *MakeThreadPool(void *param)
{

    for(;;) {
        length = sizeof(cli_addr);
        if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) { 
            exit(1);
                                                  }
    temps=socketfd;
    rc = pthread_create(&Thread[i++],NULL,ServeThread,(void *)temps);

                        }
}
void*ServeThread(void*param)
{int tsk;
tsk=(int)参数;
/*这里我正在为连接(tsk)服务,然后关闭它*/
}
void*MakeThreadPool(void*param)
{
对于(;;){
长度=sizeof(cli_addr);
如果((socketfd=accept(listenfd,(struct sockaddr*)&cli_addr,&length))<0{
出口(1);
}
temps=socketfd;
rc=pthread_create(&Thread[i++],NULL,ServeThread,(void*)temps);
}
}

当有连接时,我如何才能使accpet()继续侦听并生成AD,而不等待前一个连接完成?

您的观察不正确,
accept(2)
不等待已建立的TCP连接完成。您看到的可能是线程调度工件——主线程被新生成的线程抢占,并且在该线程完成之前不会运行


一般来说,每个连接的线程数是一个可行的策略,但您可能希望在接受连接之前创建一个线程池,而不是每次都启动一个新的线程池。

执行
malloc
将文件描述符放入其中-这将防止您遇到的争用情况。新创建的线程在完成此操作后具有释放的契约。或者(也是一个更好的解决方案)是拥有一个随时可用的线程池。使用互斥体和队列,以便在准备处理时将它们取下


更好的方法是创建一组线程,每个线程在
accept
周围都有一个互斥锁。如果需要,主线程可以加满此列表,或者如果列表太多,则要求某些线程正常终止。

默认情况下TCP套接字处于阻塞状态。你把那些旗子放好了吗

  x=fcntl(socket,F_GETFL,0);            
  fcntl(socket,F_SETFL,x | O_NONBLOCK);

您的分析错误,此代码不会等待现有连接/线程完成。尽管您可能会通过调试应用程序来影响这一点(当您在调试器中四处走动时,可能会停止所有线程)。找到另一种调试方法(例如,使用简单的printfs)和/或显示更多代码,并描述如何测试。套接字是否处于非阻塞模式?我删除了关闭(套接字),并使用web浏览器连接到web服务器,输入了web服务器URL,打开了一个新选项卡,还连接了web服务器。只有一个选项卡正在连接“当然它没有关闭连接”,但另一个选项卡正在等待“没有(在选项卡中传输数据消息)”与连接的选项卡相同。