Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While signal not received?

So I've been programming in C lately and studying Signals and POSIX threads. I know I could wait on a signal in a thread, but I've been wondering if it's possible to have a thread which contains a while loop that will keep executing forever while SIGINT is not received. So basically i'm not waiting on a signal (stopping execution of while loop) but keep executing until the signal is received. Just listening for a certain signal.

I tried googling but to no avail.

Any suggestions? Thanks in advance!!

like image 851
gEdringer Avatar asked Dec 02 '14 23:12

gEdringer


2 Answers

What about just using a simple signal handler ?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

static void sigint_handler( int signum );
volatile static int done = 0;

int main( int argc, char *argv[] )
{
   if( signal( SIGINT, sigint_handler ) == SIG_ERR ) {
      perror( "signal()" );
      exit(1);
   }

   while( !done ) {
      (void)printf( "working...\n" );
      (void)sleep( 1 );
   }

   (void)printf( "got SIGINT\n" );

   return 0;
}

void sigint_handler( int signum )
{ done = 1; }

EDIT: made done volatile, thanks to Joseph Quinsey for pointing this out in the comments. See this question for a related discussion, also this article.

like image 56
xbug Avatar answered Oct 13 '22 20:10

xbug


You can block the signal and then use sigtimedwait() with a zero timeout to poll for it.

In the main thread, before creating any other threads, block SIGINT. Subsequently created threads will inherit the signal mask, so SIGINT will be blocked in all threads:

sigset_t sigint_set;

sigemptyset(&sigint_set);
sigaddset(&sigint_set, SIGINT);    
sigprocmask(SIG_BLOCK, &sigint_set, NULL);

Then in the thread that you want to loop around polling for SIGINT:

sigset_t sigint_set;
siginfo_t info;
const struct timespec zero_timeout = { 0, 0 };

sigemptyset(&sigint_set);
sigaddset(&sigint_set, SIGINT);    

while (sigtimedwait(&sigint_set, &info, &zero_timeout) != SIGINT)
{
    /* Do something */
}
like image 28
caf Avatar answered Oct 13 '22 20:10

caf