Search code examples
cmultithreadingsignalsalarm

Signal to print message every 20 seconds (C Multithreaded program)


I am trying to print a message every 20 seconds in a multithreaded program. I have a server that has two threads. One thread waits for incoming connections and makes a new thread for the client when it connects.

I have looked at this: C: SIGALRM - alarm to display message every second but with my code, I'm not sure where I would put the loop. I am not allowed to make a new thread or use sleep() or any variation of sleep().

Code for server acceptor thread:

while((csock = accept(sock, (struct sockaddr *) &theClient, (socklen_t *) &cl)))
{
        pthread_t newClient;
        new_sock = malloc(sizeof(socket_t));
        *new_sock = csock;
        pthread_create(&newClient, NULL, getInput, (void *) new_sock)
}

The other thread is just handling the client's input. I tried putting the loop inside the above loop but then it never accepts new connections.

How would I go about doing this? Any help would be appreciated.


Solution

  • Your problem seems to be currently that accept() is blocking the thread until a new connection comes in; therefore you can't print anything.

    You could use non-blocking accept() in a loop to check for connections, and in the same loop wait until 20 seconds has passed. Note that this is very inefficient as this loop doesn't stop; it uses 100% of 1 cpu core.

    // sock is listening
    fcntl(sock,F_SETFD,O_NONBLOCK);
    
    time_t tm = time(); // Unix timestamp, in seconds.
    
    while(true) {
      csock = accept(sock, (sockaddr*)&theClient, (socklen_t*)&cl);
      if (csock==-1) {
        if (errno==EAGAIN || errno==EWOULDBLOCK); // No connection at the
                                                  // moment, we need to try
                                                  // again later.
        else break; // Some other error occurred
      }
      else { // If it is connected
        pthread_t newClient;
        new_sock = malloc(sizeof(socket_t));
        *new_sock = csock;
        pthread_create(&newClient,NULL,getInput,(void*)new_sock);
      }
    
      if (time()-tm>=20) { // At least 20 seconds have elapsed since
                           // last message.
        printf("Hello World!!\n");
        tm = time(); // Start waiting for another 20 seconds.
      }
    }
    

    Using select() to wait for a new connection would be far more efficient - you can also set a timeout which expires so that you can print your message

    Edit: You don't want to use a signal, because, as it says in the article you linked, you can't use printf from inside a signal handler. If you use the signal handler to set a flag, you won't be able to read the flag unless you use non-blocking accept() (because otherwise accept() could block for a minute but nothing prints).