0

How do we properly kill a long infinite running thread by SIGINT?

Because what I'm doing is

volatile sig_atomic_t exitRequested = 0;

void sigint_handler()
{
    printf("handler called\n");
    exitRequested = 1;
}

void* process_tickers(void* _) {

    while (1){
        printf("ticker is running\n");
        if (exitRequested == 1)
        {
            break;
        }
        if (dec_time == -1) {
            size_t bufsize = 32;
            char *buffer = malloc(32);
            size_t characters;
            characters = getline(&buffer,&bufsize,stdin);
            if (characters > 0) {
                //do something
            }
      
        }
        
    }
    return NULL;
}

Inside main I started the read by doing

int main() {
    signal(SIGINT, sigint_handler);
    pthread_t ticker_thread;
    pthread_create(&ticker_thread, NULL, process_tickers, NULL);
    insertRear(threads, &ticker_thread);
    void ** retval = NULL;
    pthread_join(ticker_thread, retval);
    while (1)
    {
         //do something;
    }
}

But I can't kill ticker_thread with SIGINT, because once I press the ctrl+c, the SIGINT would be sent to update the global variable exitRequested but inside the thread function, getline() would just sit there wait for program to enter something so it will go back to top of the loop and then it would break and by then thread will be reaped. How do I just kill thread immediately with Ctrl+C?

Alex Hu
  • 65
  • 6
  • 2
    *How do we properly kill a long infinite running thread by SIGINT?* You don't. You kill *processes* with `SIGINT`. Nor can you safely call functions such as `printf()` from within a signal handler. See https://stackoverflow.com/questions/2084830/kill-thread-in-pthread-library – Andrew Henle Dec 05 '21 at 12:36
  • The problem is you're using a blocking function `getline()` that's not interrupted on the signal. That should give you enough of a hint to figure this out... – Andrew Henle Dec 05 '21 at 12:50
  • @AndrewHenle yeah thats what I'm confused about, since there is no way to properly kill a thread on SIGINT? Can we do select() instead of getline so that way, it won't block the process of thread – Alex Hu Dec 05 '21 at 13:40
  • You're trying to solve a problem that involves a lot of things - interrupting a read from `stdin` also involves the behavior of the input stream itself - is it a terminal? Has it been redirected to a file? It could even be a socket. See https://stackoverflow.com/questions/3882379/how-to-interrupt-a-fread-call for some more information. And `getline()` is even harder to break than `fread()` because if you use `select()` on `STDIN_FILENO`, then call `getline()` it'll block still block if there's no newline but the stream is still open. And properly using `select()` on standard input is hard. – Andrew Henle Dec 05 '21 at 13:52
  • huh. Thank you. One more thing I wanna ask is that if I create multiple threads in a single for loop and put pthread_join after the thread being created, can I reap all of the threads? Or do I have to save the pid and reap them in another for loop? – Alex Hu Dec 05 '21 at 14:47
  • @AlexHu if you join a thread immediately after creating it then you might as well have called the thread function directly instead of launching a thread at all. If you want two or more threads to run concurrently then you need to create them all before you join any of them. – John Bollinger Dec 05 '21 at 15:09

0 Answers0