0

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.

Community
  • 1
  • 1
Vylic
  • 69
  • 2
  • 9
  • What is the one thread doing while waiting for incoming connections? That would seem like the place to handle this. – Scott Hunter Dec 06 '15 at 03:58
  • The thread up there is the one waiting for incoming connections. Isn't it waiting on the `accept()` method? I thought it couldn't do anything else while waiting for a connection. – Vylic Dec 06 '15 at 04:00
  • 1
    Have a look at [`setitimer`](http://linux.die.net/man/2/setitimer) or [`timer_create`](http://man7.org/linux/man-pages/man2/timer_create.2.html)+[`timer_settime`](http://man7.org/linux/man-pages/man2/timer_settime.2.html). Both can be used to set a timer where expiration can be handled via a signal. – kaylum Dec 06 '15 at 04:02
  • Ok, I'll look into them. Thanks. – Vylic Dec 06 '15 at 04:07

1 Answers1

1

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).

Alec Barber
  • 226
  • 2
  • 6
  • There are other ways to output to terminal besides `printf`. `write` for example is async safe and can be used to write to stdout. – kaylum Dec 06 '15 at 05:23