Reputation: 13
I'm doing a program that utilizes threads. I also have a SIGINT
handler that closes everything correctly, for an orderly shutdown. However, since my threads are in a while(1)
loop the pthread_join
function in my handler gets stuck and i have to press ctrl+c
a bunch of times, to close each thread singularly. How can i do this with just 1 click?
Here's my thread worker function:
void *worker(){
struct message msg;
while(1){
if(wr.fnode != NULL){
sem_wait(&tsem);
stats->nptri++;
msg.patient = *(wr.fnode);
wr_deletefnode();
sem_post(&tsem);
sleep((float)(msg.patient.ttime/1000));
msgsnd(mqid,&msg,sizeof(msg)-sizeof(long),0);
}
}
}
Upvotes: 1
Views: 763
Reputation: 70883
Two things you need to solve:
sem_wait()
)Referring 1.:
Change
while (1)
to be
while (!exit_flag)
Define exit_flag
globally
volatile sig_atomic_t exit_flag = 0;
and set it to 1
on reception of the SIGINT
signal.
To catch a signal do not setup a signal handler, but create a separate thread using sigwait()
to wait for and receive a SIGINT
.
Make sure all other threads are created blocking SIGINT
.
Referring 2.:
Keep track of all thread running by memorising their thread-ids.
After the signal-listener thread mentioned under 1. set the exit_flag
, then loop over the list of running threads and one by one
SIGINT
pthread_kill()
, in case they were stuck inside a system call, the call would return setting errno
to EINTR
.pthread_join()
.Upvotes: 0
Reputation: 11921
It's depend how you are sending signal
(SIGINT or any) to a thread
. for sending a signal to thread you should use pthread_kill()
instead of kill()
or raise()
because signal handler(signal or sigaction
) handles only processes
,not threads
.
int pthread_kill(pthread_t thread, int sig);
If you ever try to kill running thread using kill command/function OS will throw warning like Warning: Program '/bin/bash' crashed.
observe running thread using ps -eL | grep pts/0
before and after sending signal.
I hope you got something.
Upvotes: 1