为什么在关闭先前的连接套接字之前,accept()系统调用不接受新连接

时间:2012-03-22 14:43:13

标签: c linux multithreading

我正在使用Pthreads在C中使用多线程设计一个多线程Web服务器,我有一个Masterthread,它在一个循环中进行监听,当有连接时它会产生一个新线程来执行一个功能服务,而Masterthread继续听取连接。

正如我在debuging中注意到的,它一次只提供一个连接,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);

                        }
}

如果有连接而不等待前一个连接完成,我如何使accpet()contine监听产生theads?

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

执行malloc将文件描述符放入其中 - 这将防止您遇到的竞争条件。完成后,新创建的线程与free签订了合同。或者(和更好的解决方案)是拥有一个准备好的线程池。使用互斥锁和队列,以便在准备好处理时将它们摘下来。

更好,实现起来可能更简单,创建一堆线程 - 每个线程都在accept周围有一个互斥锁。如果有必要,主线程可以充值这个列表,或者如果太多那么,请一些人优雅地终止。

答案 2 :(得分:0)

TCP套接字默认是阻止的。你有这些旗帜吗?

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