2009-02-24 69 views
2

我正在用C编写一个服务器程序,其中每次客户端连接时,都会创建一个新的pthread来处理客户端的请求。当所有线程退出时,然后我的程序退出,就好像调用了exit()一样。这是一个问题 - 我该如何克服它?如何在pthread退出时保持进程退出?

可以说服务器正在运行,并且有2个客户端连接。一旦这些客户端断开连接并因此两个线程退出,那么我的服务器进程就会退出。我想要的是让我的服务器保持accept()套接字请求。通常情况下,当我使用fork()和accept()时,这是有效的。我在做什么错误,使父进程终止而不是循环无限?

代码基本上是这样的:

void *talker(void *d) { 
    int fd; 
    char buf[] = "Hello client"; 

    fd = (int)d; 

    while(1) { 
     write(fd, buf, strlen(buf)+1); 
     sleep(4); 
    } 
} 


int main(int argc, char *argv[]) { 

    pthread_t thread[50]; 

    int sockfd; 
    struct sockaddr_in client_addr; 
    int i = 0; 
    int s1; 

    /* ... other declarations */ 

    if (initialize_server_socket(portno, &sockfd) < 0) { 
    fprintf(stderr, "Could not initialize socket\n"); 
    exit(-1); 
    } 

    while(1) { 
    s1 = accept(sockfd, (struct sockaddr *)&client_addr, &n); 
    pthread_create(&(thread[i++]), NULL, talker, (void *)s1); 
    } 

    return(0); 
} 

另外:这是从问题的同一个项目我已经问(下面的链接)...虽然花费太多时间试图使用select()之后和IPC没有成功,我想由于共享地址空间的简单性,我会给线程一个旋风。

Using pipes in C for parent-child IPC makes program block

而且,大部分代码是从这里取:http://www.s5h.net/2006/06/27/pthread-socket-server-in-c/

回答

3

如果您在gdb调试它,你会发现你得到一个SIGPIPE,你的程序不处理。您可以安装SIGPIPE处理程序或忽略SIGPIPE。

原因是您的线程正在写入已关闭(由客户端)的套接字(管道),这引发了一个SIGPIPE。你应该忽略SIGPIPE后检查write()返回值:

signal(SIGPIPE, SIG_IGN); 

或处理SIGPIPE。它与2个客户端连接无关,如果您在客户端断开连接后等待4秒钟,则会得到一个SIGPIPE(就您的情况而言)。

+0

啊,在gdb中,我确实注意到了一个SIGPIPE,但是我不知道为什么那样。而且我没有意识到不检查这个(不完整的程序)会是如此灾难性的。非常感谢! – poundifdef 2009-02-24 07:57:00