I'm newbie in UNIX programming, I have a problem with signals. I'm writing multithread program, where threads can die at any moment. When thread dies it generates signal SIGUSR1 to main thread and then thread dies. Main thread gets a signal and waits for thread dead.
I wrote program like this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <signal.h>
#include <semaphore.h>
#define THREADS 3
int threads;
sem_t sem;
void signal_usr1_act(int signo,siginfo_t *inf,void *vd)
{
pthread_t *s;
fprintf(stderr,"Got USR1\n");
s=inf->si_value.sival_ptr;
pthread_join(*s,NULL);
threads--;
fprintf(stderr,"Joined!\n");
if(threads==0)sem_post(&sem);
}
void *thread_func(void*a)
{
union sigval sig_value;
sig_value.sival_ptr=a;
fprintf(stderr,"sending signal\n");
sigqueue(getpid(),SIGUSR1,sig_value); // sending pthread_t*
fprintf(stderr,"sleeping\n");
system("sleep 2"); // Any operation to make a delay
fprintf(stderr,"Stop sleeping\n");
}
int main(int argc,char **argv)
{
int i;
pthread_t pts[THREADS];
sigset_t new_mask,old_mask;
struct sigaction new_sig,old_sig;
// Adding signal action
new_sig.sa_sigaction=signal_usr1_act;
new_sig.sa_flags=SA_SIGINFO;
sigemptyset(&new_sig.sa_mask);
sigfillset(&new_sig.sa_mask);
sigaction(SIGUSR1,&new_sig,&old_sig);
// some initialisation stuff
sem_init(&sem,0,0);
threads=THREADS;
// creating mask
sigemptyset(&new_mask);
sigfillset(&new_mask);
// creating threads
pthread_sigmask(SIG_BLOCK,&new_mask,&old_mask);
for(i=0;i<THREADS;i++)
{
pthread_create(pts+i,NULL,thread_func,pts+i);
// And some other code, where we should block signals
}
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
// Waiting for threads
do{
pthread_sigmask(SIG_BLOCK,&new_mask,NULL);
fprintf(stderr,"Main is locked! Waiting for %d threads\n",threads);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
}while(sem_wait(&sem)<0);
sem_destroy(&sem);
return 0;
}
I've got a problem: some signals were not sended/received and I've got deadlock (main thread waits for signal, but signal never comes).
Program prints:
Main is locked! Waiting for 3 threads
sending signal
sleeping
Got USR1
sending signal
sleeping
sending signal
sleeping
Stop sleeping
Stop sleeping
Joined!
Got USR1
Joined!
Main is locked! Waiting for 1 threads
Stop sleeping
After it program locks.
Why some signals were not received? Program should send/recive 3 SIGUSR1 and exit, but there are only 2 SIGUSR1. Why?