poundifdef
poundifdef

Reputation: 19353

How to keep process from exiting when a pthread exits?

I am writing a server program in C wherein every time a client connects, I create a new pthread to handle the client's requests.

When all of the threads exit, however, then my program exits, as though a call to exit() has been made. This is a problem - how can I overcome it?

Lets say the server is running, and 2 clients connect. Once those clients disconnect - and thus both threads exit - then my server process exits. What I want is for my server to keep accept()ing socket requests. Ususally this works when I use fork() and accept(). What am I doing wrong such that the parent process is terminating rather than looping infinitely?

Code looks basically like this:

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

Also: this is the same project from a question I already asked (linked below)... though after spending too much time trying to use select() and IPC unsuccessfully, I figured I'd give threads a whirl because of the simplicity of shared address space.

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

Also, much of this code was taken from here: http://www.s5h.net/2006/06/27/pthread-socket-server-in-c/

Upvotes: 3

Views: 1885

Answers (1)

codelogic
codelogic

Reputation: 73622

If you debug it in gdb you'll see that you're getting a SIGPIPE, which your program doesn't handle. You can either install a SIGPIPE handler or ignore SIGPIPE.

The reason is that your thread is writing to a socket (pipe) that has been closed (by the client), which raises a SIGPIPE. You should check the return value of write() after ignoring SIGPIPE:

signal(SIGPIPE, SIG_IGN);

or handle SIGPIPE. It has nothing to do with 2 clients connecting, if you wait for 4 seconds after the client disconnects, you'll get a SIGPIPE (in your case).

Upvotes: 4

Related Questions