Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Broadcasting a Signal to All threads in Linux

Tags:

c

linux

pthreads

I want to broadcast a signal from one thread to all other threads in a process. The threads receiving that signal should handle the signal in a signal handler. How can I achieve this?


I tried the following code, but it exits by printing User defined signal 1. What's going on?

#include  <stdio.h>
#include  <signal.h>
#include  <sys/types.h>
#include  <pthread.h>

const int NTHREADS = 4;

long  prev_fact, i; 

void  SIGhandler(int);     

void  SIGhandler(int sig)
{
  printf("\nThread %lx Received a SIGUSR1.\n", pthread_self());
}

void* tfunc( void* arg )
{
  printf( "Thread %lx executing...\n", pthread_self() );

  while( 1 )
   ;
}

int main()
{
  int i;
  pthread_t t[NTHREADS];

  for( i = 0; i < NTHREADS; i++ )
   pthread_create( &t[i], NULL, tfunc, NULL );

  for( i = 0; i < NTHREADS; i++ )
   pthread_kill( t[i], SIGUSR1 );

  for( i = 0; i < NTHREADS; ++i) 
   pthread_join(t[i], NULL);

  return 0;
}
like image 584
MetallicPriest Avatar asked Feb 04 '26 14:02

MetallicPriest


2 Answers

The portable pthreads way to do this is to loop around all of the threads, executing pthread_kill() for each one. This requires you to maintain a list of all the pthread_t values representing each thread in the process.

On Linux, you can read /proc/self/task to determine the TIDs of every thread in the current process, then use tgkill() to signal them (use the result of getpid() as the tgid parameter to tgkill()).

Note that glibc does not provide a wrapper for tgkill() - you must call it using syscall().

like image 144
caf Avatar answered Feb 06 '26 09:02

caf


The following code works now...

#include  <stdio.h>
#include  <signal.h>
#include  <sys/types.h>
#include  <pthread.h>

const int NTHREADS = 4;

void  SIGhandler(int);     

void  SIGhandler(int sig)
{
     printf("\nThread %lx Received a SIGUSR1.\n", pthread_self());
}

void* tfunc( void* arg )
{
  printf( "Thread %d(%lx) executing...\n", *((unsigned int*)arg), pthread_self() );

  while( 1 )
    ;
}

int main()
{
  int i;
  int tid[NTHREADS];
  pthread_t t[NTHREADS];

  signal(SIGUSR1, SIGhandler);

  for( i = 0; i < NTHREADS; i++ )
  {
    tid[i] = i;
    pthread_create( &t[i], NULL, tfunc, tid+i );
  }

  for( i = 0; i < NTHREADS; i++ )
    pthread_kill( t[i], SIGUSR1 );

  for( i = 0; i < NTHREADS; ++i) 
    pthread_join(t[i], NULL);

  return 0;
}
like image 23
MetallicPriest Avatar answered Feb 06 '26 09:02

MetallicPriest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!