jonelearn
jonelearn

Reputation: 13

Raising SIGINT, but getting stuck in thread in c

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

Answers (2)

alk
alk

Reputation: 70883

Two things you need to solve:

  1. How to break the endless while loop
  2. How to return from blocking system call (like for example 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

  • enable them to receive SIGINT
  • signal them using pthread_kill(), in case they were stuck inside a system call, the call would return setting errno to EINTR.
  • join the thread calling pthread_join().

Upvotes: 0

Achal
Achal

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

Related Questions