2009-02-24 6 views
2

J'écris un programme serveur en C dans lequel chaque fois qu'un client se connecte, je crée un nouveau pthread pour gérer les demandes du client.Comment empêcher le processus de se fermer quand un pthread existe?

Lorsque tous les threads se terminent, cependant, mon programme se termine, comme si un appel à exit() avait été effectué. C'est un problème - comment puis-je le surmonter?

Disons que le serveur est en cours d'exécution et que 2 clients se connectent. Une fois ces clients déconnectés - et donc les deux threads sortent - alors mon processus serveur se termine. Ce que je veux, c'est que mon serveur continue à accepter les demandes de socket. Ususally cela fonctionne quand j'utilise fork() et accept(). Qu'est-ce que je fais de mal de telle sorte que le processus parent se termine plutôt que de se répéter indéfiniment?

code ressemble fondamentalement ceci:

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); 
} 

aussi: c'est le même projet d'une question que j'ai déjà demandé (lien ci-dessous) ... mais après avoir passé trop de temps à essayer d'utiliser select() et IPC sans succès, j'ai pensé que je donnerais un tourbillon aux threads en raison de la simplicité de l'espace d'adressage partagé.

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

En outre, une grande partie de ce code a été pris d'ici: http://www.s5h.net/2006/06/27/pthread-socket-server-in-c/

Répondre

3

Si vous déboguez dans gdb vous verrez que vous obtenez un SIGPIPE, que votre programme ne gère pas . Vous pouvez installer un gestionnaire SIGPIPE ou ignorer SIGPIPE.

La raison est que votre thread écrit dans une socket (pipe) qui a été fermée (par le client), ce qui soulève un SIGPIPE. Vous devriez vérifier la valeur de retour de write() après avoir ignoré SIGPIPE:

signal(SIGPIPE, SIG_IGN); 

ou la poignée SIGPIPE. Cela n'a rien à voir avec 2 clients se connectant, si vous attendez 4 secondes après la déconnexion du client, vous obtiendrez un SIGPIPE (dans votre cas).

+0

Ah, dans gdb j'ai remarqué un SIGPIPE, mais je ne pouvais pas comprendre pourquoi c'était le cas. Et je n'ai pas réalisé que ne pas vérifier cela (étant un programme incomplet) serait si catastrophique. Merci beaucoup! – poundifdef

Questions connexes